def compose(self): comp_table = decomp_inverse self_len = len(self) i = 0 out = u'' while i < self_len: starter = self[i] if starter in canon_chars and canon_chars[starter] != 0: i += 1 continue accents = [] i += 1 while i < self_len: accent = unicode(self[i]) if accent not in canon_chars or canon_chars[accent] == 0: break accents.append(accent) i += 1 if len(accents) == 0: out += starter continue out += self.composeCharacter(starter, accents) return SafeUnicode(out) def composeCharacter(self, starter, accents): accents_joined = u''.join(accents) combined = unicode(starter) + accents_joined char_len = len(combined) if combined in decomp_inverse: return decomp_inverse[combined][1] """ match = None match_len = 0 for decomp in decomp_inverse: if combined.startswith(decomp): remaining = combined[len(decomp):] poss_match = decomp_inverse[decomp][1] + remaining if len(poss_match) > match_len: match = poss_match match_len = len(match) if match: return match """ possibilities = [char for char in decomp_inverse if char[0] == starter and len(char) <= char_len] matches = [] for possible in possibilities: match = True for char in possible[1:]: if char not in accents: match = False if match: matches.append(possible) if len(matches) == 0: return combined elif len(matches) == 1: if len(matches[0]) == char_len: return decomp_inverse[matches[0]][1] out = None low_comb = 0xFFFFFF for match in matches: if match[1] not in canon_chars: continue comb_class = canon_chars[match[1]] if comb_class < low_comb: out = match low_comb = comb_class if out == None: long_match = None long_match_len = 0 for match in matches: if len(match) >= long_match_len: long_match = match long_match_len = len(long_match) out = long_match remaining = [accent for accent in accents if accent not in out] out = decomp_inverse[out][1] out += u''.join(remaining) return out