Changeset 195

Show
Ignore:
Timestamp:
04/25/08 14:33:29 (9 months ago)
Author:
tal
Message:
Added support to font.unicodeData for looking up open and close relatives for glyphs. For example, looking for the close relative of "parenleft" would return "parenright".
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • packages/defcon/trunk/Lib/defcon/objects/uniData.py

    r193 r195  
    368368                    return baseGlyphName 
    369369        return glyphName 
     370 
     371    def closeRelativeForGlyphName(self, glyphName, allowPseudoUnicode=True): 
     372        """ 
     373        >>> from defcon.objects.font import Font 
     374        >>> font = Font() 
     375        >>> font.newGlyph("parenleft") 
     376        >>> font["parenleft"].unicode = int("0028", 16) 
     377        >>> font.newGlyph("parenright") 
     378        >>> font["parenright"].unicode = int("0029", 16) 
     379        >>> font.newGlyph("parenleft.alt") 
     380        >>> font.newGlyph("parenright.alt") 
     381        >>> font.unicodeData.closeRelativeForGlyphName("parenleft", True) 
     382        'parenright' 
     383        >>> font.unicodeData.closeRelativeForGlyphName("parenleft.alt", True) 
     384        'parenright.alt' 
     385        >>> del font["parenright.alt"] 
     386        >>> font.unicodeData.closeRelativeForGlyphName("parenleft.alt", True) 
     387        'parenright' 
     388        """ 
     389        return self._openCloseSearch(glyphName, allowPseudoUnicode, unicodeTools.closeRelative) 
     390 
     391    def openRelativeForGlyphName(self, glyphName, allowPseudoUnicode=True): 
     392        """ 
     393        >>> from defcon.objects.font import Font 
     394        >>> font = Font() 
     395        >>> font.newGlyph("parenleft") 
     396        >>> font["parenleft"].unicode = int("0028", 16) 
     397        >>> font.newGlyph("parenright") 
     398        >>> font["parenright"].unicode = int("0029", 16) 
     399        >>> font.newGlyph("parenleft.alt") 
     400        >>> font.newGlyph("parenright.alt") 
     401        >>> font.unicodeData.openRelativeForGlyphName("parenright", True) 
     402        'parenleft' 
     403        >>> font.unicodeData.openRelativeForGlyphName("parenright.alt", True) 
     404        'parenleft.alt' 
     405        >>> del font["parenleft.alt"] 
     406        >>> font.unicodeData.openRelativeForGlyphName("parenright.alt", True) 
     407        'parenleft' 
     408        """ 
     409        return self._openCloseSearch(glyphName, allowPseudoUnicode, unicodeTools.openRelative) 
     410 
     411    def _openCloseSearch(self, glyphName, allowPseudoUnicode, lookup): 
     412        if allowPseudoUnicode: 
     413            uniValue = self.pseudoUnicodeForGlyphName(glyphName) 
     414        else: 
     415            uniValue = self.unicodeForGlyphName(glyphName) 
     416        if uniValue is None: 
     417            return 
     418        relativeValue = lookup(uniValue) 
     419        # no defined relative value. return. 
     420        if relativeValue is None: 
     421            return 
     422        # look for a hit on the unicode value. 
     423        # if none exists, return. 
     424        preciseMatch = self.glyphNameForUnicode(relativeValue) 
     425        if preciseMatch is None: 
     426            return 
     427        # pseudo unicode is not allowed. use precise match. 
     428        if not allowPseudoUnicode: 
     429            return preciseMatch 
     430        # add the suffix from the provided glyph name to the 
     431        # recise match and test for existence. if it does 
     432        # exist, return it. otherwise fallback to the 
     433        # precise match. 
     434        if "." in glyphName: 
     435            suffix = glyphName.split(".", 1)[1] 
     436            pseudoMatch = preciseMatch + "." + suffix 
     437            if pseudoMatch in self.getParent(): 
     438                return pseudoMatch 
     439        return preciseMatch 
    370440 
    371441    # ------- 
     
    551621                baseToGlyphNames[base] = [] 
    552622            baseToGlyphNames[base].append(glyphName) 
    553         # get the list of lgyphs with no base. 
     623        # get the list of glyphs with no base. 
    554624        noBase = baseToGlyphNames.pop(None) 
    555625        # find all bases that are not in the overall glyph names list 
  • packages/defcon/trunk/Lib/defcon/tools/unicodeTools.py

    r156 r195  
    17301730""" 
    17311731 
     1732_openClosePairText = """ 
     1733# This was automatically generated from UnicodeData.txt and then 
     1734# tweaked by hand to handle the special exceptions. 
     1735 
     17360028;LEFT PARENTHESIS;Ps 
     17370029;RIGHT PARENTHESIS;Pe 
     1738 
     1739005B;LEFT SQUARE BRACKET;Ps 
     1740005D;RIGHT SQUARE BRACKET;Pe 
     1741 
     1742007B;LEFT CURLY BRACKET;Ps 
     1743007D;RIGHT CURLY BRACKET;Pe 
     1744 
     174500AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi 
     174600BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf 
     1747 
     17480F3A;TIBETAN MARK GUG RTAGS GYON;Ps 
     17490F3B;TIBETAN MARK GUG RTAGS GYAS;Pe 
     1750 
     17510F3C;TIBETAN MARK ANG KHANG GYON;Ps 
     17520F3D;TIBETAN MARK ANG KHANG GYAS;Pe 
     1753 
     1754169B;OGHAM FEATHER MARK;Ps 
     1755169C;OGHAM REVERSED FEATHER MARK;Pe 
     1756 
     17572018;LEFT SINGLE QUOTATION MARK;Pi 
     17582019;RIGHT SINGLE QUOTATION MARK;Pf 
     1759 
     1760201C;LEFT DOUBLE QUOTATION MARK;Pi 
     1761201D;RIGHT DOUBLE QUOTATION MARK;Pf 
     1762 
     17632039;SINGLE LEFT-POINTING ANGLE QUOTATION MARK;Pi 
     1764203A;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK;Pf 
     1765 
     17662045;LEFT SQUARE BRACKET WITH QUILL;Ps 
     17672046;RIGHT SQUARE BRACKET WITH QUILL;Pe 
     1768 
     1769207D;SUPERSCRIPT LEFT PARENTHESIS;Ps 
     1770207E;SUPERSCRIPT RIGHT PARENTHESIS;Pe 
     1771 
     1772208D;SUBSCRIPT LEFT PARENTHESIS;Ps 
     1773208E;SUBSCRIPT RIGHT PARENTHESIS;Pe 
     1774 
     17752329;LEFT-POINTING ANGLE BRACKET;Ps 
     1776232A;RIGHT-POINTING ANGLE BRACKET;Pe 
     1777 
     17782768;MEDIUM LEFT PARENTHESIS ORNAMENT;Ps 
     17792769;MEDIUM RIGHT PARENTHESIS ORNAMENT;Pe 
     1780 
     1781276A;MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT;Ps 
     1782276B;MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT;Pe 
     1783 
     1784276C;MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps 
     1785276D;MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe 
     1786 
     1787276E;HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT;Ps 
     1788276F;HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT;Pe 
     1789 
     17902770;HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps 
     17912771;HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe 
     1792 
     17932772;LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT;Ps 
     17942773;LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT;Pe 
     1795 
     17962774;MEDIUM LEFT CURLY BRACKET ORNAMENT;Ps 
     17972775;MEDIUM RIGHT CURLY BRACKET ORNAMENT;Pe 
     1798 
     179927C5;LEFT S-SHAPED BAG DELIMITER;Ps 
     180027C6;RIGHT S-SHAPED BAG DELIMITER;Pe 
     1801 
     180227E6;MATHEMATICAL LEFT WHITE SQUARE BRACKET;Ps 
     180327E7;MATHEMATICAL RIGHT WHITE SQUARE BRACKET;Pe 
     1804 
     180527E8;MATHEMATICAL LEFT ANGLE BRACKET;Ps 
     180627E9;MATHEMATICAL RIGHT ANGLE BRACKET;Pe 
     1807 
     180827EA;MATHEMATICAL LEFT DOUBLE ANGLE BRACKET;Ps 
     180927EB;MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET;Pe 
     1810 
     18112983;LEFT WHITE CURLY BRACKET;Ps 
     18122984;RIGHT WHITE CURLY BRACKET;Pe 
     1813 
     18142985;LEFT WHITE PARENTHESIS;Ps 
     18152986;RIGHT WHITE PARENTHESIS;Pe 
     1816 
     18172987;Z NOTATION LEFT IMAGE BRACKET;Ps 
     18182988;Z NOTATION RIGHT IMAGE BRACKET;Pe 
     1819 
     18202989;Z NOTATION LEFT BINDING BRACKET;Ps 
     1821298A;Z NOTATION RIGHT BINDING BRACKET;Pe 
     1822 
     1823298B;LEFT SQUARE BRACKET WITH UNDERBAR;Ps 
     1824298C;RIGHT SQUARE BRACKET WITH UNDERBAR;Pe 
     1825 
     1826298D;LEFT SQUARE BRACKET WITH TICK IN TOP CORNER;Ps 
     1827298E;RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Pe 
     1828 
     1829298F;LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Ps 
     18302990;RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER;Pe 
     1831 
     18322991;LEFT ANGLE BRACKET WITH DOT;Ps 
     18332992;RIGHT ANGLE BRACKET WITH DOT;Pe 
     1834 
     18352993;LEFT ARC LESS-THAN BRACKET;Ps 
     18362994;RIGHT ARC GREATER-THAN BRACKET;Pe 
     1837 
     18382995;DOUBLE LEFT ARC GREATER-THAN BRACKET;Ps 
     18392996;DOUBLE RIGHT ARC LESS-THAN BRACKET;Pe 
     1840 
     18412997;LEFT BLACK TORTOISE SHELL BRACKET;Ps 
     18422998;RIGHT BLACK TORTOISE SHELL BRACKET;Pe 
     1843 
     184429D8;LEFT WIGGLY FENCE;Ps 
     184529D9;RIGHT WIGGLY FENCE;Pe 
     1846 
     184729DA;LEFT DOUBLE WIGGLY FENCE;Ps 
     184829DB;RIGHT DOUBLE WIGGLY FENCE;Pe 
     1849 
     185029FC;LEFT-POINTING CURVED ANGLE BRACKET;Ps 
     185129FD;RIGHT-POINTING CURVED ANGLE BRACKET;Pe 
     1852 
     18532E02;LEFT SUBSTITUTION BRACKET;Pi 
     18542E03;RIGHT SUBSTITUTION BRACKET;Pf 
     1855 
     18562E04;LEFT DOTTED SUBSTITUTION BRACKET;Pi 
     18572E05;RIGHT DOTTED SUBSTITUTION BRACKET;Pf 
     1858 
     18592E09;LEFT TRANSPOSITION BRACKET;Pi 
     18602E0A;RIGHT TRANSPOSITION BRACKET;Pf 
     1861 
     18622E0C;LEFT RAISED OMISSION BRACKET;Pi 
     18632E0D;RIGHT RAISED OMISSION BRACKET;Pf 
     1864 
     18652E1C;LEFT LOW PARAPHRASE BRACKET;Pi 
     18662E1D;RIGHT LOW PARAPHRASE BRACKET;Pf 
     1867 
     18683008;LEFT ANGLE BRACKET;Ps 
     18693009;RIGHT ANGLE BRACKET;Pe 
     1870 
     1871300A;LEFT DOUBLE ANGLE BRACKET;Ps 
     1872300B;RIGHT DOUBLE ANGLE BRACKET;Pe 
     1873 
     1874300C;LEFT CORNER BRACKET;Ps 
     1875300D;RIGHT CORNER BRACKET;Pe 
     1876 
     1877300E;LEFT WHITE CORNER BRACKET;Ps 
     1878300F;RIGHT WHITE CORNER BRACKET;Pe 
     1879 
     18803010;LEFT BLACK LENTICULAR BRACKET;Ps 
     18813011;RIGHT BLACK LENTICULAR BRACKET;Pe 
     1882 
     18833014;LEFT TORTOISE SHELL BRACKET;Ps 
     18843015;RIGHT TORTOISE SHELL BRACKET;Pe 
     1885 
     18863016;LEFT WHITE LENTICULAR BRACKET;Ps 
     18873017;RIGHT WHITE LENTICULAR BRACKET;Pe 
     1888 
     18893018;LEFT WHITE TORTOISE SHELL BRACKET;Ps 
     18903019;RIGHT WHITE TORTOISE SHELL BRACKET;Pe 
     1891 
     1892301A;LEFT WHITE SQUARE BRACKET;Ps 
     1893301B;RIGHT WHITE SQUARE BRACKET;Pe 
     1894 
     1895FD3E;ORNATE LEFT PARENTHESIS;Ps 
     1896FD3F;ORNATE RIGHT PARENTHESIS;Pe 
     1897 
     1898FE17;PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET;Ps 
     1899FE18;PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET;Pe 
     1900 
     1901FE35;PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS;Ps 
     1902FE36;PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS;Pe 
     1903 
     1904FE37;PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET;Ps 
     1905FE38;PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET;Pe 
     1906 
     1907FE39;PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET;Ps 
     1908FE3A;PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET;Pe 
     1909 
     1910FE3B;PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET;Ps 
     1911FE3C;PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET;Pe 
     1912 
     1913FE3D;PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET;Ps 
     1914FE3E;PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET;Pe 
     1915 
     1916FE3F;PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET;Ps 
     1917FE40;PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET;Pe 
     1918 
     1919FE41;PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET;Ps 
     1920FE42;PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET;Pe 
     1921 
     1922FE43;PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET;Ps 
     1923FE44;PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET;Pe 
     1924 
     1925FE47;PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET;Ps 
     1926FE48;PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET;Pe 
     1927 
     1928FE59;SMALL LEFT PARENTHESIS;Ps 
     1929FE5A;SMALL RIGHT PARENTHESIS;Pe 
     1930 
     1931FE5B;SMALL LEFT CURLY BRACKET;Ps 
     1932FE5C;SMALL RIGHT CURLY BRACKET;Pe 
     1933 
     1934FE5D;SMALL LEFT TORTOISE SHELL BRACKET;Ps 
     1935FE5E;SMALL RIGHT TORTOISE SHELL BRACKET;Pe 
     1936 
     1937FF08;FULLWIDTH LEFT PARENTHESIS;Ps 
     1938FF09;FULLWIDTH RIGHT PARENTHESIS;Pe 
     1939 
     1940FF3B;FULLWIDTH LEFT SQUARE BRACKET;Ps 
     1941FF3D;FULLWIDTH RIGHT SQUARE BRACKET;Pe 
     1942 
     1943FF5B;FULLWIDTH LEFT CURLY BRACKET;Ps 
     1944FF5D;FULLWIDTH RIGHT CURLY BRACKET;Pe 
     1945 
     1946FF5F;FULLWIDTH LEFT WHITE PARENTHESIS;Ps 
     1947FF60;FULLWIDTH RIGHT WHITE PARENTHESIS;Pe 
     1948 
     1949FF62;HALFWIDTH LEFT CORNER BRACKET;Ps 
     1950FF63;HALFWIDTH RIGHT CORNER BRACKET;Pe 
     1951 
     1952301D;REVERSED DOUBLE PRIME QUOTATION MARK;Ps 
     1953301E;DOUBLE PRIME QUOTATION MARK;Pe 
     1954 
     1955# Special Exceptions 
     1956# These have flipped relatives that are already mapped above. 
     1957 
     1958201F;DOUBLE HIGH-REVERSED-9 QUOTATION MARK;Pi 
     1959201D;RIGHT DOUBLE QUOTATION MARK;Pf # already mapped 
     1960 
     1961201E;DOUBLE LOW-9 QUOTATION MARK;Ps 
     1962201D;RIGHT DOUBLE QUOTATION MARK;Pf # already mapped 
     1963 
     1964201B;SINGLE HIGH-REVERSED-9 QUOTATION MARK;Pi 
     19652019;RIGHT SINGLE QUOTATION MARK;Pf # already mapped 
     1966 
     1967201A;SINGLE LOW-9 QUOTATION MARK;Ps 
     19682019;RIGHT SINGLE QUOTATION MARK;Pf # already mapped 
     1969 
     1970301D;REVERSED DOUBLE PRIME QUOTATION MARK;Ps  # already mapped 
     1971301F;LOW DOUBLE PRIME QUOTATION MARK;Pe 
     1972""" 
     1973 
    17321974import unicodedata 
    17331975 
    17341976# load the data 
    17351977 
    1736 def _parse(text): 
     1978def _parseRangeText(text): 
    17371979    result = [] 
    17381980    orderedTags = [] 
     
    17571999    return result, orderedTags 
    17582000 
    1759 _scripts, orderedScripts = _parse(_scriptsText) 
     2001_scripts, orderedScripts = _parseRangeText(_scriptsText) 
    17602002orderedScripts.append("Unknown") 
    1761 _blocks, orderedBlocks = _parse(_blocksText) 
     2003_blocks, orderedBlocks = _parseRangeText(_blocksText) 
    17622004 
    17632005orderedCategories = """Lu 
     
    17922034Cn""".splitlines() 
    17932035 
     2036_openToClose = {} 
     2037_closeToOpen = {} 
     2038 
     2039openValue = None 
     2040for line in _openClosePairText.splitlines(): 
     2041    line = line.split("#")[0].strip() 
     2042    if not line: 
     2043        continue 
     2044    value, name, category = line.split(";") 
     2045    value = int(value, 16) 
     2046    if openValue is not None: 
     2047        closeValue = value 
     2048        if openValue not in _openToClose: 
     2049            _openToClose[openValue] = closeValue 
     2050        if closeValue not in _closeToOpen: 
     2051            _closeToOpen[closeValue] = openValue 
     2052        openValue = None 
     2053    else: 
     2054        openValue = value 
     2055 
    17942056# functions 
    17952057 
     
    18182080    return decomposedUniValue 
    18192081 
     2082def openRelative(value): 
     2083    return _closeToOpen.get(value) 
     2084 
     2085def closeRelative(value): 
     2086    return _openToClose.get(value) 
     2087 
    18202088def category(value): 
    18212089    c = unichr(value) 
     
    18232091 
    18242092def script(value): 
    1825     scriptName = _search(value, _scripts) 
     2093    scriptName = _searchRanges(value, _scripts) 
    18262094    if scriptName is None: 
    18272095        scriptName = "Unknown" 
     
    18292097 
    18302098def block(value): 
    1831     blockName = _search(value, _blocks) 
     2099    blockName = _searchRanges(value, _blocks) 
    18322100    if blockName is None: 
    18332101        blockName = "No_Block" 
    18342102    return blockName 
    18352103 
    1836 def _search(value, available): 
     2104def _searchRanges(value, available): 
    18372105    count = len(available) 
    18382106    if count == 0: 
     
    18482116    minValue, maxValue, name = test 
    18492117    if value < minValue: 
    1850         return _search(value, lessRange) 
     2118        return _searchRanges(value, lessRange) 
    18512119    elif value > maxValue: 
    1852         return _search(value, greaterRange) 
     2120        return _searchRanges(value, greaterRange) 
    18532121    else: 
    18542122        return name