Пример #1
0
 def __init__(self, filename=None, transform=None):
     if filename is None:
         self.root = etree.ElementTree()
     else:
         tree = etree.parse(filename)
         self.root = tree.getroot()
     self.transform = transform
Пример #2
0
def dump(
    value,
    fp,
    sort_keys=True,
    skipkeys=False,
    use_builtin_types=None,
    pretty_print=True,
):
    if not hasattr(fp, "write"):
        raise AttributeError("'%s' object has no attribute 'write'" %
                             type(fp).__name__)
    root = etree.Element("plist", version="1.0")
    el = totree(
        value,
        sort_keys=sort_keys,
        skipkeys=skipkeys,
        use_builtin_types=use_builtin_types,
        pretty_print=pretty_print,
    )
    root.append(el)
    tree = etree.ElementTree(root)
    # we write the doctype ourselves instead of using the 'doctype' argument
    # of 'write' method, becuse lxml will force adding a '\n' even when
    # pretty_print is False.
    if pretty_print:
        header = b"\n".join((XML_DECLARATION, PLIST_DOCTYPE, b""))
    else:
        header = XML_DECLARATION + PLIST_DOCTYPE
    fp.write(header)
    tree.write(fp,
               encoding="utf-8",
               pretty_print=pretty_print,
               xml_declaration=False)
Пример #3
0
def dump(
    value: PlistEncodable,
    fp: IO[bytes],
    sort_keys: bool = True,
    skipkeys: bool = False,
    use_builtin_types: Optional[bool] = None,
    pretty_print: bool = True,
) -> None:
    """Write a Python object to a plist file.

    Args:
        value: An object to write.
        fp: A file opened for writing.
        sort_keys (bool): Whether keys of dictionaries should be sorted.
        skipkeys (bool): Whether to silently skip non-string dictionary
            keys.
        use_builtin_types (bool): If true, byte strings will be
            encoded in Base-64 and wrapped in a ``data`` tag; if
            false, they will be either stored as ASCII strings or an
            exception raised if they cannot be represented. Defaults
        pretty_print (bool): Whether to indent the output.
        indent_level (int): Level of indentation when serializing.

    Raises:
        ``TypeError``
            if non-string dictionary keys are serialized
            and ``skipkeys`` is false.
        ``ValueError``
            if non-representable binary data is present
            and `use_builtin_types` is false.
    """

    if not hasattr(fp, "write"):
        raise AttributeError("'%s' object has no attribute 'write'" %
                             type(fp).__name__)
    root = etree.Element("plist", version="1.0")
    el = totree(
        value,
        sort_keys=sort_keys,
        skipkeys=skipkeys,
        use_builtin_types=use_builtin_types,
        pretty_print=pretty_print,
    )
    root.append(el)
    tree = etree.ElementTree(root)
    # we write the doctype ourselves instead of using the 'doctype' argument
    # of 'write' method, becuse lxml will force adding a '\n' even when
    # pretty_print is False.
    if pretty_print:
        header = b"\n".join((XML_DECLARATION, PLIST_DOCTYPE, b""))
    else:
        header = XML_DECLARATION + PLIST_DOCTYPE
    fp.write(header)
    tree.write(  # type: ignore
        fp,
        encoding="utf-8",
        pretty_print=pretty_print,
        xml_declaration=False,
    )
Пример #4
0
 def getGlyphXML(glyphDir, glyphFileName):
     glyphPath = os.path.join(glyphDir, glyphFileName)  # default
     etRoot = ET.ElementTree()
     glifXML = etRoot.parse(glyphPath)
     outlineXML = glifXML.find("outline")
     try:
         widthXML = glifXML.find("advance")
         if widthXML is not None:
             width = round(ast.literal_eval(widthXML.get("width", '0')), 9)
         else:
             width = 0
     except UFOParseError as e:
         print(f"Error. skipping glyph '{glyphFileName}' because "
               f"of parse error: {str(e)}")
         return None, None, None
     return width, glifXML, outlineXML
Пример #5
0
    def buildGlyphHashValue(self,
                            width,
                            outlineXML,
                            glyphName,
                            useDefaultGlyphDir,
                            level=0):
        """
        glyphData must be the official <outline> XML from a GLIF.
        We skip contours with only one point.
        """
        dataList = ["w%s" % norm_float(round(width, 9))]
        if level > 10:
            raise UFOParseError(
                "In parsing component, exceeded 10 levels of reference. "
                "'%s'. " % (glyphName))
        # <outline> tag is optional per spec., e.g. space glyph
        # does not necessarily have it.
        if outlineXML is not None:
            for childContour in outlineXML:
                if childContour.tag == "contour":
                    if len(childContour) < 2:
                        continue
                    for child in childContour:
                        if child.tag == "point":
                            ptType = child.get("type")
                            pointType = '' if ptType is None else ptType[0]
                            x = self._rd_val(child.get("x"))
                            y = self._rd_val(child.get("y"))
                            dataList.append("%s%s%s" % (pointType, x, y))

                elif childContour.tag == "component":
                    # append the component hash.
                    compGlyphName = childContour.get("base")

                    if compGlyphName is None:
                        raise UFOParseError(
                            "'%s' is missing the 'base' attribute in a "
                            "component." % glyphName)

                    dataList.append("%s%s" % ("base:", compGlyphName))

                    if useDefaultGlyphDir:
                        try:
                            componentPath = self.getGlyphDefaultPath(
                                compGlyphName)
                        except KeyError:
                            raise UFOParseError(
                                "'%s' component glyph is missing from "
                                "contents.plist." % (compGlyphName))
                    else:
                        # If we are not necessarily using the default layer
                        # for the main glyph, then a missing component may not
                        # have been processed, and may just be in the default
                        # layer. We need to look for component glyphs in the
                        # src list first, then in the defualt layer.
                        try:
                            componentPath = self.getGlyphSrcPath(compGlyphName)
                            if not os.path.exists(componentPath):
                                componentPath = self.getGlyphDefaultPath(
                                    compGlyphName)
                        except KeyError:
                            try:
                                componentPath = self.getGlyphDefaultPath(
                                    compGlyphName)
                            except KeyError:
                                raise UFOParseError(
                                    "'%s' component glyph is missing from "
                                    "contents.plist." % (compGlyphName))

                    if not os.path.exists(componentPath):
                        raise UFOParseError(
                            "'%s' component file is missing: '%s'." %
                            (compGlyphName, componentPath))

                    etRoot = ET.ElementTree()

                    # Collect transform values
                    for trans_key, flbk_val in COMP_TRANSFORM.items():
                        value = childContour.get(trans_key, flbk_val)
                        dataList.append(self._rd_val(value))

                    componentXML = etRoot.parse(componentPath)
                    componentOutlineXML = componentXML.find("outline")
                    _, componentDataList = self.buildGlyphHashValue(
                        width, componentOutlineXML, glyphName,
                        useDefaultGlyphDir, level + 1)
                    dataList.extend(componentDataList)
        data = "".join(dataList)
        if len(data) >= 128:
            data = hashlib.sha512(data.encode("ascii")).hexdigest()
        return data, dataList