Edgewall Software

Ticket #230: unicode_wiki_links.diff

File unicode_wiki_links.diff, 29.6 KB (added by mgood, 5 years ago)

alternate solution for unicode WikiPageNames

  • trac/wiki/api.py

     
    3131from trac.core import * 
    3232from trac.util import reversed 
    3333from trac.util.html import html 
     34from trac.util.text import uniupper, unilower 
    3435 
    3536 
    3637class IWikiChangeListener(Interface): 
     
    443444            helper_re = re.compile(r'\?P<([a-z\d_]+)>') 
    444445            for rule in syntax: 
    445446                helpers += helper_re.findall(rule)[1:] 
    446             rules = re.compile('(?:' + '|'.join(syntax) + ')', re.UNICODE) 
     447            rules = re.compile('(?:%s)' % '|'.join(syntax), re.UNICODE) 
    447448            self._external_handlers = handlers 
    448449            self._helper_patterns = helpers 
    449450            self._compiled_rules = rules 
     
    491492 
    492493    def get_wiki_syntax(self): 
    493494        from trac.wiki.formatter import Formatter 
    494         lower = r'(?<![A-Z0-9_])' # No Upper case when looking behind 
    495         upper = r'(?<![a-z0-9_])' # No Lower case when looking behind 
     495 
    496496        wiki_page_name = ( 
    497             r"\w%s(?:\w%s)+(?:\w%s(?:\w%s)*[\w/]%s)+" % # wiki words 
    498             (upper, lower, upper, lower, lower) + 
    499             r"(?:@\d+)?" # optional version 
    500             r"(?:#%s)?" % self.XML_NAME + # optional fragment id 
    501             r"(?=:(?:\Z|\s)|[^:a-zA-Z]|\s|\Z)" # what should follow it 
     497            ur"[%s][%s]+(?:[%s][%s]*[%s/])+" # wiki words 
     498            % (uniupper, unilower, uniupper, unilower, unilower) + 
     499            ur"(?:@\d+)?" # optional version 
     500            ur"(?:#%s)?" % self.XML_NAME + # optional fragment id 
     501            ur"(?=:(?:\Z|\s)|[^:%s%s]|\s|\Z)" # what should follow it 
     502            % (unilower, uniupper) 
    502503            ) 
    503504 
    504         def check_unicode_camelcase(pagename): 
    505             if pagename[0].isupper(): 
    506                 if pagename[1].islower(): 
    507                     i, n = 2, len(pagename) 
    508                     second_upper = False 
    509                     while i < n - 2: 
    510                         if pagename[i].isupper(): 
    511                             second_upper = True 
    512                             i += 1 
    513                             if not pagename[i].islower(): 
    514                                 return False 
    515                         elif pagename[i] in '@#': 
    516                             return second_upper and pagename[i-1].islower() 
    517                         i += 1 
    518                     return second_upper and pagename[n-1].islower() 
    519             return False 
    520          
    521505        # Regular WikiPageNames 
    522506        def wikipagename_link(formatter, match, fullmatch): 
    523             if not check_unicode_camelcase(match): 
    524                 return match 
    525507            return self._format_link(formatter, 'wiki', match, 
    526508                                     self.format_page_name(match), 
    527509                                     self.ignore_missing_pages) 
    528510         
    529         yield (r"!?(?<!/)\b" + # start at a word boundary but not after '/' 
     511        yield (ur"!?(?<!/)\b" + # start at a word boundary but not after '/' 
    530512               wiki_page_name, wikipagename_link) 
    531513 
    532514        # [WikiPageNames with label] 
    533515        def wikipagename_with_label_link(formatter, match, fullmatch): 
    534516            page, label = match[1:-1].split(' ', 1) 
    535             if not check_unicode_camelcase(page): 
    536                 return label 
    537517            return self._format_link(formatter, 'wiki', page, label.strip(), 
    538518                                     self.ignore_missing_pages) 
    539         yield (r"!?\[%s\s+(?:%s|[^\]]+)\]" % (wiki_page_name, 
     519        yield (ur"!?\[%s\s+(?:%s|[^\]]+)\]" % (wiki_page_name, 
    540520                                              Formatter.QUOTED_STRING), 
    541521               wikipagename_with_label_link) 
    542522 
    543523        # MoinMoin's ["internal free link"]  
    544524        def internal_free_link(fmt, m, fullmatch):  
    545525            return self._format_link(fmt, 'wiki', m[2:-2], m[2:-2], False)  
    546         yield (r"!?\[(?:%s)\]" % Formatter.QUOTED_STRING, internal_free_link)  
     526        yield (ur"!?\[(?:%s)\]" % Formatter.QUOTED_STRING, internal_free_link)  
    547527 
    548528    def get_link_resolvers(self): 
    549529        def link_resolver(formatter, ns, target, label): 
  • trac/wiki/tests/wikisyntax.py

     
    5252------------------------------ 
    5353============================== WikiPageNames conformance (unicode) 
    5454SmÅogstore should produce a link 
     55and so should wiki:SmÅogstore 
    5556------------------------------ 
    5657<p> 
    5758<a class="missing wiki" href="/wiki/Sm%C3%85ogstore" rel="nofollow">SmÅogstore?</a> should produce a link 
     59and so should <a class="missing wiki" href="/wiki/Sm%C3%85ogstore" rel="nofollow">wiki:SmÅogstore?</a> 
    5860</p> 
    5961------------------------------ 
    6062============================== More WikiPageNames conformance 
  • trac/wiki/formatter.py

     
    186186 
    187187    QUOTED_STRING = r"'[^']+'|\"[^\"]+\"" 
    188188 
    189     SHREF_TARGET_FIRST = r"[\w/?!#@](?<!_)" # we don't want "_" 
     189    SHREF_TARGET_FIRST = r"[a-zA-Z0-9/?!#@]" # we don't want "_" 
    190190    SHREF_TARGET_MIDDLE = r"(?:\|(?=[^|\s])|[^|<>\s])" 
    191     SHREF_TARGET_LAST = r"[\w/=](?<!_)" # we don't want "_" 
     191    SHREF_TARGET_LAST = r"[a-zA-Z0-9/=]" # we don't want "_" 
    192192 
    193193    LHREF_RELATIVE_TARGET = r"[/.#][^\s[\]]*" 
    194194 
  • trac/util/text.py

     
    219219        outlines.append(''.join(s)) 
    220220    return '\n'.join(outlines) 
    221221 
     222uniupper = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8' \ 
     223           u'\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8' \ 
     224           u'\xd9\xda\xdb\xdc\xdd\xde\u0100\u0102\u0104\u0106\u0108\u010a' \ 
     225           u'\u010c\u010e\u0110\u0112\u0114\u0116\u0118\u011a\u011c\u011e' \ 
     226           u'\u0120\u0122\u0124\u0126\u0128\u012a\u012c\u012e\u0130\u0132' \ 
     227           u'\u0134\u0136\u0139\u013b\u013d\u013f\u0141\u0143\u0145\u0147' \ 
     228           u'\u014a\u014c\u014e\u0150\u0152\u0154\u0156\u0158\u015a\u015c' \ 
     229           u'\u015e\u0160\u0162\u0164\u0166\u0168\u016a\u016c\u016e\u0170' \ 
     230           u'\u0172\u0174\u0176\u0178\u0179\u017b\u017d\u0181\u0182\u0184' \ 
     231           u'\u0186\u0187\u0189\u018a\u018b\u018e\u018f\u0190\u0191\u0193' \ 
     232           u'\u0194\u0196\u0197\u0198\u019c\u019d\u019f\u01a0\u01a2\u01a4' \ 
     233           u'\u01a6\u01a7\u01a9\u01ac\u01ae\u01af\u01b1\u01b2\u01b3\u01b5' \ 
     234           u'\u01b7\u01b8\u01bc\u01c4\u01c7\u01ca\u01cd\u01cf\u01d1\u01d3' \ 
     235           u'\u01d5\u01d7\u01d9\u01db\u01de\u01e0\u01e2\u01e4\u01e6\u01e8' \ 
     236           u'\u01ea\u01ec\u01ee\u01f1\u01f4\u01f6\u01f7\u01f8\u01fa\u01fc' \ 
     237           u'\u01fe\u0200\u0202\u0204\u0206\u0208\u020a\u020c\u020e\u0210' \ 
     238           u'\u0212\u0214\u0216\u0218\u021a\u021c\u021e\u0220\u0222\u0224' \ 
     239           u'\u0226\u0228\u022a\u022c\u022e\u0230\u0232\u0386\u0388\u0389' \ 
     240           u'\u038a\u038c\u038e\u038f\u0391\u0392\u0393\u0394\u0395\u0396' \ 
     241           u'\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0' \ 
     242           u'\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab' \ 
     243           u'\u03d2\u03d3\u03d4\u03d8\u03da\u03dc\u03de\u03e0\u03e2\u03e4' \ 
     244           u'\u03e6\u03e8\u03ea\u03ec\u03ee\u03f4\u0400\u0401\u0402\u0403' \ 
     245           u'\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b\u040c\u040d' \ 
     246           u'\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417' \ 
     247           u'\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421' \ 
     248           u'\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b' \ 
     249           u'\u042c\u042d\u042e\u042f\u0460\u0462\u0464\u0466\u0468\u046a' \ 
     250           u'\u046c\u046e\u0470\u0472\u0474\u0476\u0478\u047a\u047c\u047e' \ 
     251           u'\u0480\u048a\u048c\u048e\u0490\u0492\u0494\u0496\u0498\u049a' \ 
     252           u'\u049c\u049e\u04a0\u04a2\u04a4\u04a6\u04a8\u04aa\u04ac\u04ae' \ 
     253           u'\u04b0\u04b2\u04b4\u04b6\u04b8\u04ba\u04bc\u04be\u04c0\u04c1' \ 
     254           u'\u04c3\u04c5\u04c7\u04c9\u04cb\u04cd\u04d0\u04d2\u04d4\u04d6' \ 
     255           u'\u04d8\u04da\u04dc\u04de\u04e0\u04e2\u04e4\u04e6\u04e8\u04ea' \ 
     256           u'\u04ec\u04ee\u04f0\u04f2\u04f4\u04f8\u0500\u0502\u0504\u0506' \ 
     257           u'\u0508\u050a\u050c\u050e\u0531\u0532\u0533\u0534\u0535\u0536' \ 
     258           u'\u0537\u0538\u0539\u053a\u053b\u053c\u053d\u053e\u053f\u0540' \ 
     259           u'\u0541\u0542\u0543\u0544\u0545\u0546\u0547\u0548\u0549\u054a' \ 
     260           u'\u054b\u054c\u054d\u054e\u054f\u0550\u0551\u0552\u0553\u0554' \ 
     261           u'\u0555\u0556\u10a0\u10a1\u10a2\u10a3\u10a4\u10a5\u10a6\u10a7' \ 
     262           u'\u10a8\u10a9\u10aa\u10ab\u10ac\u10ad\u10ae\u10af\u10b0\u10b1' \ 
     263           u'\u10b2\u10b3\u10b4\u10b5\u10b6\u10b7\u10b8\u10b9\u10ba\u10bb' \ 
     264           u'\u10bc\u10bd\u10be\u10bf\u10c0\u10c1\u10c2\u10c3\u10c4\u10c5' \ 
     265           u'\u1e00\u1e02\u1e04\u1e06\u1e08\u1e0a\u1e0c\u1e0e\u1e10\u1e12' \ 
     266           u'\u1e14\u1e16\u1e18\u1e1a\u1e1c\u1e1e\u1e20\u1e22\u1e24\u1e26' \ 
     267           u'\u1e28\u1e2a\u1e2c\u1e2e\u1e30\u1e32\u1e34\u1e36\u1e38\u1e3a' \ 
     268           u'\u1e3c\u1e3e\u1e40\u1e42\u1e44\u1e46\u1e48\u1e4a\u1e4c\u1e4e' \ 
     269           u'\u1e50\u1e52\u1e54\u1e56\u1e58\u1e5a\u1e5c\u1e5e\u1e60\u1e62' \ 
     270           u'\u1e64\u1e66\u1e68\u1e6a\u1e6c\u1e6e\u1e70\u1e72\u1e74\u1e76' \ 
     271           u'\u1e78\u1e7a\u1e7c\u1e7e\u1e80\u1e82\u1e84\u1e86\u1e88\u1e8a' \ 
     272           u'\u1e8c\u1e8e\u1e90\u1e92\u1e94\u1ea0\u1ea2\u1ea4\u1ea6\u1ea8' \ 
     273           u'\u1eaa\u1eac\u1eae\u1eb0\u1eb2\u1eb4\u1eb6\u1eb8\u1eba\u1ebc' \ 
     274           u'\u1ebe\u1ec0\u1ec2\u1ec4\u1ec6\u1ec8\u1eca\u1ecc\u1ece\u1ed0' \ 
     275           u'\u1ed2\u1ed4\u1ed6\u1ed8\u1eda\u1edc\u1ede\u1ee0\u1ee2\u1ee4' \ 
     276           u'\u1ee6\u1ee8\u1eea\u1eec\u1eee\u1ef0\u1ef2\u1ef4\u1ef6\u1ef8' \ 
     277           u'\u1f08\u1f09\u1f0a\u1f0b\u1f0c\u1f0d\u1f0e\u1f0f\u1f18\u1f19' \ 
     278           u'\u1f1a\u1f1b\u1f1c\u1f1d\u1f28\u1f29\u1f2a\u1f2b\u1f2c\u1f2d' \ 
     279           u'\u1f2e\u1f2f\u1f38\u1f39\u1f3a\u1f3b\u1f3c\u1f3d\u1f3e\u1f3f' \ 
     280           u'\u1f48\u1f49\u1f4a\u1f4b\u1f4c\u1f4d\u1f59\u1f5b\u1f5d\u1f5f' \ 
     281           u'\u1f68\u1f69\u1f6a\u1f6b\u1f6c\u1f6d\u1f6e\u1f6f\u1fb8\u1fb9' \ 
     282           u'\u1fba\u1fbb\u1fc8\u1fc9\u1fca\u1fcb\u1fd8\u1fd9\u1fda\u1fdb' \ 
     283           u'\u1fe8\u1fe9\u1fea\u1feb\u1fec\u1ff8\u1ff9\u1ffa\u1ffb\u2102' \ 
     284           u'\u2107\u210b\u210c\u210d\u2110\u2111\u2112\u2115\u2119\u211a' \ 
     285           u'\u211b\u211c\u211d\u2124\u2126\u2128\u212a\u212b\u212c\u212d' \ 
     286           u'\u2130\u2131\u2133\u213e\u213f\u2145\uff21\uff22\uff23\uff24' \ 
     287           u'\uff25\uff26\uff27\uff28\uff29\uff2a\uff2b\uff2c\uff2d\uff2e' \ 
     288           u'\uff2f\uff30\uff31\uff32\uff33\uff34\uff35\uff36\uff37\uff38' \ 
     289           u'\uff39\uff3a\U00010400\U00010401\U00010402\U00010403' \ 
     290           u'\U00010404\U00010405\U00010406\U00010407\U00010408\U00010409' \ 
     291           u'\U0001040a\U0001040b\U0001040c\U0001040d\U0001040e\U0001040f' \ 
     292           u'\U00010410\U00010411\U00010412\U00010413\U00010414\U00010415' \ 
     293           u'\U00010416\U00010417\U00010418\U00010419\U0001041a\U0001041b' \ 
     294           u'\U0001041c\U0001041d\U0001041e\U0001041f\U00010420\U00010421' \ 
     295           u'\U00010422\U00010423\U00010424\U00010425\U0001d400\U0001d401' \ 
     296           u'\U0001d402\U0001d403\U0001d404\U0001d405\U0001d406\U0001d407' \ 
     297           u'\U0001d408\U0001d409\U0001d40a\U0001d40b\U0001d40c\U0001d40d' \ 
     298           u'\U0001d40e\U0001d40f\U0001d410\U0001d411\U0001d412\U0001d413' \ 
     299           u'\U0001d414\U0001d415\U0001d416\U0001d417\U0001d418\U0001d419' \ 
     300           u'\U0001d434\U0001d435\U0001d436\U0001d437\U0001d438\U0001d439' \ 
     301           u'\U0001d43a\U0001d43b\U0001d43c\U0001d43d\U0001d43e\U0001d43f' \ 
     302           u'\U0001d440\U0001d441\U0001d442\U0001d443\U0001d444\U0001d445' \ 
     303           u'\U0001d446\U0001d447\U0001d448\U0001d449\U0001d44a\U0001d44b' \ 
     304           u'\U0001d44c\U0001d44d\U0001d468\U0001d469\U0001d46a\U0001d46b' \ 
     305           u'\U0001d46c\U0001d46d\U0001d46e\U0001d46f\U0001d470\U0001d471' \ 
     306           u'\U0001d472\U0001d473\U0001d474\U0001d475\U0001d476\U0001d477' \ 
     307           u'\U0001d478\U0001d479\U0001d47a\U0001d47b\U0001d47c\U0001d47d' \ 
     308           u'\U0001d47e\U0001d47f\U0001d480\U0001d481\U0001d49c\U0001d49e' \ 
     309           u'\U0001d49f\U0001d4a2\U0001d4a5\U0001d4a6\U0001d4a9\U0001d4aa' \ 
     310           u'\U0001d4ab\U0001d4ac\U0001d4ae\U0001d4af\U0001d4b0\U0001d4b1' \ 
     311           u'\U0001d4b2\U0001d4b3\U0001d4b4\U0001d4b5\U0001d4d0\U0001d4d1' \ 
     312           u'\U0001d4d2\U0001d4d3\U0001d4d4\U0001d4d5\U0001d4d6\U0001d4d7' \ 
     313           u'\U0001d4d8\U0001d4d9\U0001d4da\U0001d4db\U0001d4dc\U0001d4dd' \ 
     314           u'\U0001d4de\U0001d4df\U0001d4e0\U0001d4e1\U0001d4e2\U0001d4e3' \ 
     315           u'\U0001d4e4\U0001d4e5\U0001d4e6\U0001d4e7\U0001d4e8\U0001d4e9' \ 
     316           u'\U0001d504\U0001d505\U0001d507\U0001d508\U0001d509\U0001d50a' \ 
     317           u'\U0001d50d\U0001d50e\U0001d50f\U0001d510\U0001d511\U0001d512' \ 
     318           u'\U0001d513\U0001d514\U0001d516\U0001d517\U0001d518\U0001d519' \ 
     319           u'\U0001d51a\U0001d51b\U0001d51c\U0001d538\U0001d539\U0001d53b' \ 
     320           u'\U0001d53c\U0001d53d\U0001d53e\U0001d540\U0001d541\U0001d542' \ 
     321           u'\U0001d543\U0001d544\U0001d546\U0001d54a\U0001d54b\U0001d54c' \ 
     322           u'\U0001d54d\U0001d54e\U0001d54f\U0001d550\U0001d56c\U0001d56d' \ 
     323           u'\U0001d56e\U0001d56f\U0001d570\U0001d571\U0001d572\U0001d573' \ 
     324           u'\U0001d574\U0001d575\U0001d576\U0001d577\U0001d578\U0001d579' \ 
     325           u'\U0001d57a\U0001d57b\U0001d57c\U0001d57d\U0001d57e\U0001d57f' \ 
     326           u'\U0001d580\U0001d581\U0001d582\U0001d583\U0001d584\U0001d585' \ 
     327           u'\U0001d5a0\U0001d5a1\U0001d5a2\U0001d5a3\U0001d5a4\U0001d5a5' \ 
     328           u'\U0001d5a6\U0001d5a7\U0001d5a8\U0001d5a9\U0001d5aa\U0001d5ab' \ 
     329           u'\U0001d5ac\U0001d5ad\U0001d5ae\U0001d5af\U0001d5b0\U0001d5b1' \ 
     330           u'\U0001d5b2\U0001d5b3\U0001d5b4\U0001d5b5\U0001d5b6\U0001d5b7' \ 
     331           u'\U0001d5b8\U0001d5b9\U0001d5d4\U0001d5d5\U0001d5d6\U0001d5d7' \ 
     332           u'\U0001d5d8\U0001d5d9\U0001d5da\U0001d5db\U0001d5dc\U0001d5dd' \ 
     333           u'\U0001d5de\U0001d5df\U0001d5e0\U0001d5e1\U0001d5e2\U0001d5e3' \ 
     334           u'\U0001d5e4\U0001d5e5\U0001d5e6\U0001d5e7\U0001d5e8\U0001d5e9' \ 
     335           u'\U0001d5ea\U0001d5eb\U0001d5ec\U0001d5ed\U0001d608\U0001d609' \ 
     336           u'\U0001d60a\U0001d60b\U0001d60c\U0001d60d\U0001d60e\U0001d60f' \ 
     337           u'\U0001d610\U0001d611\U0001d612\U0001d613\U0001d614\U0001d615' \ 
     338           u'\U0001d616\U0001d617\U0001d618\U0001d619\U0001d61a\U0001d61b' \ 
     339           u'\U0001d61c\U0001d61d\U0001d61e\U0001d61f\U0001d620\U0001d621' \ 
     340           u'\U0001d63c\U0001d63d\U0001d63e\U0001d63f\U0001d640\U0001d641' \ 
     341           u'\U0001d642\U0001d643\U0001d644\U0001d645\U0001d646\U0001d647' \ 
     342           u'\U0001d648\U0001d649\U0001d64a\U0001d64b\U0001d64c\U0001d64d' \ 
     343           u'\U0001d64e\U0001d64f\U0001d650\U0001d651\U0001d652\U0001d653' \ 
     344           u'\U0001d654\U0001d655\U0001d670\U0001d671\U0001d672\U0001d673' \ 
     345           u'\U0001d674\U0001d675\U0001d676\U0001d677\U0001d678\U0001d679' \ 
     346           u'\U0001d67a\U0001d67b\U0001d67c\U0001d67d\U0001d67e\U0001d67f' \ 
     347           u'\U0001d680\U0001d681\U0001d682\U0001d683\U0001d684\U0001d685' \ 
     348           u'\U0001d686\U0001d687\U0001d688\U0001d689\U0001d6a8\U0001d6a9' \ 
     349           u'\U0001d6aa\U0001d6ab\U0001d6ac\U0001d6ad\U0001d6ae\U0001d6af' \ 
     350           u'\U0001d6b0\U0001d6b1\U0001d6b2\U0001d6b3\U0001d6b4\U0001d6b5' \ 
     351           u'\U0001d6b6\U0001d6b7\U0001d6b8\U0001d6b9\U0001d6ba\U0001d6bb' \ 
     352           u'\U0001d6bc\U0001d6bd\U0001d6be\U0001d6bf\U0001d6c0\U0001d6e2' \ 
     353           u'\U0001d6e3\U0001d6e4\U0001d6e5\U0001d6e6\U0001d6e7\U0001d6e8' \ 
     354           u'\U0001d6e9\U0001d6ea\U0001d6eb\U0001d6ec\U0001d6ed\U0001d6ee' \ 
     355           u'\U0001d6ef\U0001d6f0\U0001d6f1\U0001d6f2\U0001d6f3\U0001d6f4' \ 
     356           u'\U0001d6f5\U0001d6f6\U0001d6f7\U0001d6f8\U0001d6f9\U0001d6fa' \ 
     357           u'\U0001d71c\U0001d71d\U0001d71e\U0001d71f\U0001d720\U0001d721' \ 
     358           u'\U0001d722\U0001d723\U0001d724\U0001d725\U0001d726\U0001d727' \ 
     359           u'\U0001d728\U0001d729\U0001d72a\U0001d72b\U0001d72c\U0001d72d' \ 
     360           u'\U0001d72e\U0001d72f\U0001d730\U0001d731\U0001d732\U0001d733' \ 
     361           u'\U0001d734\U0001d756\U0001d757\U0001d758\U0001d759\U0001d75a' \ 
     362           u'\U0001d75b\U0001d75c\U0001d75d\U0001d75e\U0001d75f\U0001d760' \ 
     363           u'\U0001d761\U0001d762\U0001d763\U0001d764\U0001d765\U0001d766' \ 
     364           u'\U0001d767\U0001d768\U0001d769\U0001d76a\U0001d76b\U0001d76c' \ 
     365           u'\U0001d76d\U0001d76e\U0001d790\U0001d791\U0001d792\U0001d793' \ 
     366           u'\U0001d794\U0001d795\U0001d796\U0001d797\U0001d798\U0001d799' \ 
     367           u'\U0001d79a\U0001d79b\U0001d79c\U0001d79d\U0001d79e\U0001d79f' \ 
     368           u'\U0001d7a0\U0001d7a1\U0001d7a2\U0001d7a3\U0001d7a4\U0001d7a5' \ 
     369           u'\U0001d7a6\U0001d7a7\U0001d7a8' 
     370 
     371unilower = u'abcdefghijklmnopqrstuvwxyz\xaa\xb5\xba\xdf\xe0\xe1\xe2\xe3\xe4' \ 
     372           u'\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3' \ 
     373           u'\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\u0101\u0103\u0105' \ 
     374           u'\u0107\u0109\u010b\u010d\u010f\u0111\u0113\u0115\u0117\u0119' \ 
     375           u'\u011b\u011d\u011f\u0121\u0123\u0125\u0127\u0129\u012b\u012d' \ 
     376           u'\u012f\u0131\u0133\u0135\u0137\u0138\u013a\u013c\u013e\u0140' \ 
     377           u'\u0142\u0144\u0146\u0148\u0149\u014b\u014d\u014f\u0151\u0153' \ 
     378           u'\u0155\u0157\u0159\u015b\u015d\u015f\u0161\u0163\u0165\u0167' \ 
     379           u'\u0169\u016b\u016d\u016f\u0171\u0173\u0175\u0177\u017a\u017c' \ 
     380           u'\u017e\u017f\u0180\u0183\u0185\u0188\u018c\u018d\u0192\u0195' \ 
     381           u'\u0199\u019a\u019b\u019e\u01a1\u01a3\u01a5\u01a8\u01aa\u01ab' \ 
     382           u'\u01ad\u01b0\u01b4\u01b6\u01b9\u01ba\u01bd\u01be\u01bf\u01c6' \ 
     383           u'\u01c9\u01cc\u01ce\u01d0\u01d2\u01d4\u01d6\u01d8\u01da\u01dc' \ 
     384           u'\u01dd\u01df\u01e1\u01e3\u01e5\u01e7\u01e9\u01eb\u01ed\u01ef' \ 
     385           u'\u01f0\u01f3\u01f5\u01f9\u01fb\u01fd\u01ff\u0201\u0203\u0205' \ 
     386           u'\u0207\u0209\u020b\u020d\u020f\u0211\u0213\u0215\u0217\u0219' \ 
     387           u'\u021b\u021d\u021f\u0223\u0225\u0227\u0229\u022b\u022d\u022f' \ 
     388           u'\u0231\u0233\u0250\u0251\u0252\u0253\u0254\u0255\u0256\u0257' \ 
     389           u'\u0258\u0259\u025a\u025b\u025c\u025d\u025e\u025f\u0260\u0261' \ 
     390           u'\u0262\u0263\u0264\u0265\u0266\u0267\u0268\u0269\u026a\u026b' \ 
     391           u'\u026c\u026d\u026e\u026f\u0270\u0271\u0272\u0273\u0274\u0275' \ 
     392           u'\u0276\u0277\u0278\u0279\u027a\u027b\u027c\u027d\u027e\u027f' \ 
     393           u'\u0280\u0281\u0282\u0283\u0284\u0285\u0286\u0287\u0288\u0289' \ 
     394           u'\u028a\u028b\u028c\u028d\u028e\u028f\u0290\u0291\u0292\u0293' \ 
     395           u'\u0294\u0295\u0296\u0297\u0298\u0299\u029a\u029b\u029c\u029d' \ 
     396           u'\u029e\u029f\u02a0\u02a1\u02a2\u02a3\u02a4\u02a5\u02a6\u02a7' \ 
     397           u'\u02a8\u02a9\u02aa\u02ab\u02ac\u02ad\u0390\u03ac\u03ad\u03ae' \ 
     398           u'\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8' \ 
     399           u'\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2' \ 
     400           u'\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc' \ 
     401           u'\u03cd\u03ce\u03d0\u03d1\u03d5\u03d6\u03d7\u03d9\u03db\u03dd' \ 
     402           u'\u03df\u03e1\u03e3\u03e5\u03e7\u03e9\u03eb\u03ed\u03ef\u03f0' \ 
     403           u'\u03f1\u03f2\u03f3\u03f5\u0430\u0431\u0432\u0433\u0434\u0435' \ 
     404           u'\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f' \ 
     405           u'\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449' \ 
     406           u'\u044a\u044b\u044c\u044d\u044e\u044f\u0450\u0451\u0452\u0453' \ 
     407           u'\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u045d' \ 
     408           u'\u045e\u045f\u0461\u0463\u0465\u0467\u0469\u046b\u046d\u046f' \ 
     409           u'\u0471\u0473\u0475\u0477\u0479\u047b\u047d\u047f\u0481\u048b' \ 
     410           u'\u048d\u048f\u0491\u0493\u0495\u0497\u0499\u049b\u049d\u049f' \ 
     411           u'\u04a1\u04a3\u04a5\u04a7\u04a9\u04ab\u04ad\u04af\u04b1\u04b3' \ 
     412           u'\u04b5\u04b7\u04b9\u04bb\u04bd\u04bf\u04c2\u04c4\u04c6\u04c8' \ 
     413           u'\u04ca\u04cc\u04ce\u04d1\u04d3\u04d5\u04d7\u04d9\u04db\u04dd' \ 
     414           u'\u04df\u04e1\u04e3\u04e5\u04e7\u04e9\u04eb\u04ed\u04ef\u04f1' \ 
     415           u'\u04f3\u04f5\u04f9\u0501\u0503\u0505\u0507\u0509\u050b\u050d' \ 
     416           u'\u050f\u0561\u0562\u0563\u0564\u0565\u0566\u0567\u0568\u0569' \ 
     417           u'\u056a\u056b\u056c\u056d\u056e\u056f\u0570\u0571\u0572\u0573' \ 
     418           u'\u0574\u0575\u0576\u0577\u0578\u0579\u057a\u057b\u057c\u057d' \ 
     419           u'\u057e\u057f\u0580\u0581\u0582\u0583\u0584\u0585\u0586\u0587' \ 
     420           u'\u1e01\u1e03\u1e05\u1e07\u1e09\u1e0b\u1e0d\u1e0f\u1e11\u1e13' \ 
     421           u'\u1e15\u1e17\u1e19\u1e1b\u1e1d\u1e1f\u1e21\u1e23\u1e25\u1e27' \ 
     422           u'\u1e29\u1e2b\u1e2d\u1e2f\u1e31\u1e33\u1e35\u1e37\u1e39\u1e3b' \ 
     423           u'\u1e3d\u1e3f\u1e41\u1e43\u1e45\u1e47\u1e49\u1e4b\u1e4d\u1e4f' \ 
     424           u'\u1e51\u1e53\u1e55\u1e57\u1e59\u1e5b\u1e5d\u1e5f\u1e61\u1e63' \ 
     425           u'\u1e65\u1e67\u1e69\u1e6b\u1e6d\u1e6f\u1e71\u1e73\u1e75\u1e77' \ 
     426           u'\u1e79\u1e7b\u1e7d\u1e7f\u1e81\u1e83\u1e85\u1e87\u1e89\u1e8b' \ 
     427           u'\u1e8d\u1e8f\u1e91\u1e93\u1e95\u1e96\u1e97\u1e98\u1e99\u1e9a' \ 
     428           u'\u1e9b\u1ea1\u1ea3\u1ea5\u1ea7\u1ea9\u1eab\u1ead\u1eaf\u1eb1' \ 
     429           u'\u1eb3\u1eb5\u1eb7\u1eb9\u1ebb\u1ebd\u1ebf\u1ec1\u1ec3\u1ec5' \ 
     430           u'\u1ec7\u1ec9\u1ecb\u1ecd\u1ecf\u1ed1\u1ed3\u1ed5\u1ed7\u1ed9' \ 
     431           u'\u1edb\u1edd\u1edf\u1ee1\u1ee3\u1ee5\u1ee7\u1ee9\u1eeb\u1eed' \ 
     432           u'\u1eef\u1ef1\u1ef3\u1ef5\u1ef7\u1ef9\u1f00\u1f01\u1f02\u1f03' \ 
     433           u'\u1f04\u1f05\u1f06\u1f07\u1f10\u1f11\u1f12\u1f13\u1f14\u1f15' \ 
     434           u'\u1f20\u1f21\u1f22\u1f23\u1f24\u1f25\u1f26\u1f27\u1f30\u1f31' \ 
     435           u'\u1f32\u1f33\u1f34\u1f35\u1f36\u1f37\u1f40\u1f41\u1f42\u1f43' \ 
     436           u'\u1f44\u1f45\u1f50\u1f51\u1f52\u1f53\u1f54\u1f55\u1f56\u1f57' \ 
     437           u'\u1f60\u1f61\u1f62\u1f63\u1f64\u1f65\u1f66\u1f67\u1f70\u1f71' \ 
     438           u'\u1f72\u1f73\u1f74\u1f75\u1f76\u1f77\u1f78\u1f79\u1f7a\u1f7b' \ 
     439           u'\u1f7c\u1f7d\u1f80\u1f81\u1f82\u1f83\u1f84\u1f85\u1f86\u1f87' \ 
     440           u'\u1f90\u1f91\u1f92\u1f93\u1f94\u1f95\u1f96\u1f97\u1fa0\u1fa1' \ 
     441           u'\u1fa2\u1fa3\u1fa4\u1fa5\u1fa6\u1fa7\u1fb0\u1fb1\u1fb2\u1fb3' \ 
     442           u'\u1fb4\u1fb6\u1fb7\u1fbe\u1fc2\u1fc3\u1fc4\u1fc6\u1fc7\u1fd0' \ 
     443           u'\u1fd1\u1fd2\u1fd3\u1fd6\u1fd7\u1fe0\u1fe1\u1fe2\u1fe3\u1fe4' \ 
     444           u'\u1fe5\u1fe6\u1fe7\u1ff2\u1ff3\u1ff4\u1ff6\u1ff7\u2071\u207f' \ 
     445           u'\u210a\u210e\u210f\u2113\u212f\u2134\u2139\u213d\u2146\u2147' \ 
     446           u'\u2148\u2149\ufb00\ufb01\ufb02\ufb03\ufb04\ufb05\ufb06\ufb13' \ 
     447           u'\ufb14\ufb15\ufb16\ufb17\uff41\uff42\uff43\uff44\uff45\uff46' \ 
     448           u'\uff47\uff48\uff49\uff4a\uff4b\uff4c\uff4d\uff4e\uff4f\uff50' \ 
     449           u'\uff51\uff52\uff53\uff54\uff55\uff56\uff57\uff58\uff59\uff5a' \ 
     450           u'\U00010428\U00010429\U0001042a\U0001042b\U0001042c\U0001042d' \ 
     451           u'\U0001042e\U0001042f\U00010430\U00010431\U00010432\U00010433' \ 
     452           u'\U00010434\U00010435\U00010436\U00010437\U00010438\U00010439' \ 
     453           u'\U0001043a\U0001043b\U0001043c\U0001043d\U0001043e\U0001043f' \ 
     454           u'\U00010440\U00010441\U00010442\U00010443\U00010444\U00010445' \ 
     455           u'\U00010446\U00010447\U00010448\U00010449\U0001044a\U0001044b' \ 
     456           u'\U0001044c\U0001044d\U0001d41a\U0001d41b\U0001d41c\U0001d41d' \ 
     457           u'\U0001d41e\U0001d41f\U0001d420\U0001d421\U0001d422\U0001d423' \ 
     458           u'\U0001d424\U0001d425\U0001d426\U0001d427\U0001d428\U0001d429' \ 
     459           u'\U0001d42a\U0001d42b\U0001d42c\U0001d42d\U0001d42e\U0001d42f' \ 
     460           u'\U0001d430\U0001d431\U0001d432\U0001d433\U0001d44e\U0001d44f' \ 
     461           u'\U0001d450\U0001d451\U0001d452\U0001d453\U0001d454\U0001d456' \ 
     462           u'\U0001d457\U0001d458\U0001d459\U0001d45a\U0001d45b\U0001d45c' \ 
     463           u'\U0001d45d\U0001d45e\U0001d45f\U0001d460\U0001d461\U0001d462' \ 
     464           u'\U0001d463\U0001d464\U0001d465\U0001d466\U0001d467\U0001d482' \ 
     465           u'\U0001d483\U0001d484\U0001d485\U0001d486\U0001d487\U0001d488' \ 
     466           u'\U0001d489\U0001d48a\U0001d48b\U0001d48c\U0001d48d\U0001d48e' \ 
     467           u'\U0001d48f\U0001d490\U0001d491\U0001d492\U0001d493\U0001d494' \ 
     468           u'\U0001d495\U0001d496\U0001d497\U0001d498\U0001d499\U0001d49a' \ 
     469           u'\U0001d49b\U0001d4b6\U0001d4b7\U0001d4b8\U0001d4b9\U0001d4bb' \ 
     470           u'\U0001d4bd\U0001d4be\U0001d4bf\U0001d4c0\U0001d4c2\U0001d4c3' \ 
     471           u'\U0001d4c5\U0001d4c6\U0001d4c7\U0001d4c8\U0001d4c9\U0001d4ca' \ 
     472           u'\U0001d4cb\U0001d4cc\U0001d4cd\U0001d4ce\U0001d4cf\U0001d4ea' \ 
     473           u'\U0001d4eb\U0001d4ec\U0001d4ed\U0001d4ee\U0001d4ef\U0001d4f0' \ 
     474           u'\U0001d4f1\U0001d4f2\U0001d4f3\U0001d4f4\U0001d4f5\U0001d4f6' \ 
     475           u'\U0001d4f7\U0001d4f8\U0001d4f9\U0001d4fa\U0001d4fb\U0001d4fc' \ 
     476           u'\U0001d4fd\U0001d4fe\U0001d4ff\U0001d500\U0001d501\U0001d502' \ 
     477           u'\U0001d503\U0001d51e\U0001d51f\U0001d520\U0001d521\U0001d522' \ 
     478           u'\U0001d523\U0001d524\U0001d525\U0001d526\U0001d527\U0001d528' \ 
     479           u'\U0001d529\U0001d52a\U0001d52b\U0001d52c\U0001d52d\U0001d52e' \ 
     480           u'\U0001d52f\U0001d530\U0001d531\U0001d532\U0001d533\U0001d534' \ 
     481           u'\U0001d535\U0001d536\U0001d537\U0001d552\U0001d553\U0001d554' \ 
     482           u'\U0001d555\U0001d556\U0001d557\U0001d558\U0001d559\U0001d55a' \ 
     483           u'\U0001d55b\U0001d55c\U0001d55d\U0001d55e\U0001d55f\U0001d560' \ 
     484           u'\U0001d561\U0001d562\U0001d563\U0001d564\U0001d565\U0001d566' \ 
     485           u'\U0001d567\U0001d568\U0001d569\U0001d56a\U0001d56b\U0001d586' \ 
     486           u'\U0001d587\U0001d588\U0001d589\U0001d58a\U0001d58b\U0001d58c' \ 
     487           u'\U0001d58d\U0001d58e\U0001d58f\U0001d590\U0001d591\U0001d592' \ 
     488           u'\U0001d593\U0001d594\U0001d595\U0001d596\U0001d597\U0001d598' \ 
     489           u'\U0001d599\U0001d59a\U0001d59b\U0001d59c\U0001d59d\U0001d59e' \ 
     490           u'\U0001d59f\U0001d5ba\U0001d5bb\U0001d5bc\U0001d5bd\U0001d5be' \ 
     491           u'\U0001d5bf\U0001d5c0\U0001d5c1\U0001d5c2\U0001d5c3\U0001d5c4' \ 
     492           u'\U0001d5c5\U0001d5c6\U0001d5c7\U0001d5c8\U0001d5c9\U0001d5ca' \ 
     493           u'\U0001d5cb\U0001d5cc\U0001d5cd\U0001d5ce\U0001d5cf\U0001d5d0' \ 
     494           u'\U0001d5d1\U0001d5d2\U0001d5d3\U0001d5ee\U0001d5ef\U0001d5f0' \ 
     495           u'\U0001d5f1\U0001d5f2\U0001d5f3\U0001d5f4\U0001d5f5\U0001d5f6' \ 
     496           u'\U0001d5f7\U0001d5f8\U0001d5f9\U0001d5fa\U0001d5fb\U0001d5fc' \ 
     497           u'\U0001d5fd\U0001d5fe\U0001d5ff\U0001d600\U0001d601\U0001d602' \ 
     498           u'\U0001d603\U0001d604\U0001d605\U0001d606\U0001d607\U0001d622' \ 
     499           u'\U0001d623\U0001d624\U0001d625\U0001d626\U0001d627\U0001d628' \ 
     500           u'\U0001d629\U0001d62a\U0001d62b\U0001d62c\U0001d62d\U0001d62e' \ 
     501           u'\U0001d62f\U0001d630\U0001d631\U0001d632\U0001d633\U0001d634' \ 
     502           u'\U0001d635\U0001d636\U0001d637\U0001d638\U0001d639\U0001d63a' \ 
     503           u'\U0001d63b\U0001d656\U0001d657\U0001d658\U0001d659\U0001d65a' \ 
     504           u'\U0001d65b\U0001d65c\U0001d65d\U0001d65e\U0001d65f\U0001d660' \ 
     505           u'\U0001d661\U0001d662\U0001d663\U0001d664\U0001d665\U0001d666' \ 
     506           u'\U0001d667\U0001d668\U0001d669\U0001d66a\U0001d66b\U0001d66c' \ 
     507           u'\U0001d66d\U0001d66e\U0001d66f\U0001d68a\U0001d68b\U0001d68c' \ 
     508           u'\U0001d68d\U0001d68e\U0001d68f\U0001d690\U0001d691\U0001d692' \ 
     509           u'\U0001d693\U0001d694\U0001d695\U0001d696\U0001d697\U0001d698' \ 
     510           u'\U0001d699\U0001d69a\U0001d69b\U0001d69c\U0001d69d\U0001d69e' \ 
     511           u'\U0001d69f\U0001d6a0\U0001d6a1\U0001d6a2\U0001d6a3\U0001d6c2' \ 
     512           u'\U0001d6c3\U0001d6c4\U0001d6c5\U0001d6c6\U0001d6c7\U0001d6c8' \ 
     513           u'\U0001d6c9\U0001d6ca\U0001d6cb\U0001d6cc\U0001d6cd\U0001d6ce' \ 
     514           u'\U0001d6cf\U0001d6d0\U0001d6d1\U0001d6d2\U0001d6d3\U0001d6d4' \ 
     515           u'\U0001d6d5\U0001d6d6\U0001d6d7\U0001d6d8\U0001d6d9\U0001d6da' \ 
     516           u'\U0001d6dc\U0001d6dd\U0001d6de\U0001d6df\U0001d6e0\U0001d6e1' \ 
     517           u'\U0001d6fc\U0001d6fd\U0001d6fe\U0001d6ff\U0001d700\U0001d701' \ 
     518           u'\U0001d702\U0001d703\U0001d704\U0001d705\U0001d706\U0001d707' \ 
     519           u'\U0001d708\U0001d709\U0001d70a\U0001d70b\U0001d70c\U0001d70d' \ 
     520           u'\U0001d70e\U0001d70f\U0001d710\U0001d711\U0001d712\U0001d713' \ 
     521           u'\U0001d714\U0001d716\U0001d717\U0001d718\U0001d719\U0001d71a' \ 
     522           u'\U0001d71b\U0001d736\U0001d737\U0001d738\U0001d739\U0001d73a' \ 
     523           u'\U0001d73b\U0001d73c\U0001d73d\U0001d73e\U0001d73f\U0001d740' \ 
     524           u'\U0001d741\U0001d742\U0001d743\U0001d744\U0001d745\U0001d746' \ 
     525           u'\U0001d747\U0001d748\U0001d749\U0001d74a\U0001d74b\U0001d74c' \ 
     526           u'\U0001d74d\U0001d74e\U0001d750\U0001d751\U0001d752\U0001d753' \ 
     527           u'\U0001d754\U0001d755\U0001d770\U0001d771\U0001d772\U0001d773' \ 
     528           u'\U0001d774\U0001d775\U0001d776\U0001d777\U0001d778\U0001d779' \ 
     529           u'\U0001d77a\U0001d77b\U0001d77c\U0001d77d\U0001d77e\U0001d77f' \ 
     530           u'\U0001d780\U0001d781\U0001d782\U0001d783\U0001d784\U0001d785' \ 
     531           u'\U0001d786\U0001d787\U0001d788\U0001d78a\U0001d78b\U0001d78c' \ 
     532           u'\U0001d78d\U0001d78e\U0001d78f\U0001d7aa\U0001d7ab\U0001d7ac' \ 
     533           u'\U0001d7ad\U0001d7ae\U0001d7af\U0001d7b0\U0001d7b1\U0001d7b2' \ 
     534           u'\U0001d7b3\U0001d7b4\U0001d7b5\U0001d7b6\U0001d7b7\U0001d7b8' \ 
     535           u'\U0001d7b9\U0001d7ba\U0001d7bb\U0001d7bc\U0001d7bd\U0001d7be' \ 
     536           u'\U0001d7bf\U0001d7c0\U0001d7c1\U0001d7c2\U0001d7c4\U0001d7c5' \ 
     537           u'\U0001d7c6\U0001d7c7\U0001d7c8\U0001d7c9'