def parse_line(self, line): line = line.strip() # get rid of eol characters parts = line.split(";") # split by the ;s parts = filter(lambda s: s != "", parts) # remove whitespace name = None char_parts_num = None char_parts = [] for part in parts: elements = part.split() elements = list(filter(lambda s: s != "", elements)) # remove whitespace try: key = elements[0] if len(elements) < 2: msg = "Composit definition key without data: %s" % repr( line) raise ParseError(msg) else: elements = elements[1:] data = " ".join(elements) if key == "CC": name = elements[0] char_parts_num = float(elements[1]) elif key == "PCC": name = elements[0] delta_x = int(elements[1]) delta_y = int(elements[2]) char_parts.append(( name, delta_x, delta_y, )) else: raise ParseError("Unknown element in composit: %s" % \ repr(line)) except IndexError: msg = "Illegal number of elements in composit char: %s" % \ repr(line) raise ParseError(msg) if name is None: raise ParseError("Character name missing from composit char: %s"%\ repr(line)) if char_parts_num != len(char_parts): warn("Composit char parts count mismatch: %s (not %i elements)" %\ (repr(line), char_part_num,)) self.set(name, char_parts)
def __init__(self, line_iterator, info, parent, implicit_keyword=False): """ @param line_iterator: Line iterator (see below) seek()) with the file pointer at the beginning of the first line for this section @param info: The rest of the section keyword's line (in a line 'StartDirection 0' it would be ' 0' @param implicit_keyword: Boolean indicating whether this section started without a keyword. True implies that this section ends with the end of file. """ keyword.__init__(self, info) self._all = [] try: if self.info is not None: self.info = self.info_cls(self.info) except ValueError: raise ParseError("Can't parse %s as %s" % \ ( repr(info), self.info_cls.__name__, )) self.implicit_keyword = implicit_keyword self.parse(line_iterator, parent) self.check()
def __init__(self, info): if "true" in info.lower(): self.info = True elif "false" in info.lower(): self.info = False else: raise ParseError("%s needs boolean argument" % \ ( self.__class__.__name__, ))
def cls(self, keyword): if keyword.startswith("Start"): keyword = keyword[5:] for a in self: if a.__name__ == keyword: return a raise ParseError("Unknown keyword: %s" % repr(keyword))
def add_keyword(self, keyword, info): if keyword in self: tpl = ( self.__class__.__name__, keyword, ) raise ParseError("Section %s already has keyword %s" % tpl) else: cls = self.keywords.cls(keyword) obj = cls(info) self.set(keyword, obj.value())
def __init__(self, info): parts = info.split() info = [] for part in parts: info.append(float(part)) if len(info) != self.tuple_size: raise ParseError("%s needs %i number arguments" % \ ( self.__class__.__name__, self.tuple_size, )) self.info = tuple(info)
def ps_hex_int(data): """ Return integer value of a PostScript hexadecimal literal. They look like <12AB> und so. """ match = ps_hex_int_re.match(data) if match is None: raise ParseError("Illegal hexadecimal representation: %s" % repr(data)) else: data = match.group(1) return int(data, 16)
def add_subsection(self, line_iterator, keyword, info, implicit_start_stop=False): subsection_class = self.subsections.cls(keyword) section_object = subsection_class(line_iterator, info, self, implicit_start_stop) if keyword.startswith("Start"): keyword = keyword[5:] if section_object.multiple == 0: if keyword in self: tpl = ( keyword, self.__class__.__name__, ) raise ParseError("Multiple %s sections in %s" % tpl) self.set(keyword, section_object) else: try: if info is None: idx = 0 else: idx = int(info) if keyword not in self: l = [] for a in range(section_object.multiple): l.append(None) self.set(keyword, l) else: l = self.get(keyword) l[idx] = section_object #subsection_class(line_iterator, info, self) except ValueError: raise ParseError("Can't parse %s into int" % repr(info))
def parse_line(self, line): elements = line.split() elements = filter(lambda a: a != "", elements) if len(elements) != 6: raise ParseError("Illegal TrackKern dataset: %s" % repr(line)) degree = int(elements[0]) rest = elements[1:] rest = map(float, rest) tpl = tuple([degree] + rest) self.set(degree, tpl)
def parse(self, line_iterator, parent): while True: line = line_iterator.readline() if line == "": raise ParseError("Unexpected end of file") elif line.strip().startswith("End%s" % self.__class__.__name__): return # end of section elif line.strip() == "": continue # empty line else: # pass the line self.parse_line(line)
def parse_afm(fp): """ Parse afm file pointed to by fp. Return a FontMetrics object. """ lines = line_iterator(fp) first_line = lines.readline() parts = first_line.split() if parts[0] != "StartFontMetrics" or len(parts) != 2: raise ParseError("Not a valid AFM file!") version = float(parts[1]) if version > 4.1: warn("This parser only knows AFM specification v. 4.1.") try: return FontMetrics(lines, None, parts[1]) except ParseError as e: e.args = (e.args[0] + (" (line: %i)" % lines.line_number), ) raise
def parse_line(self, line): line = line.strip() # get rid of eol characters parts = line.split(";") # split by the ;s parts = filter(lambda s: s != "", parts) # remove whitespace info = {} for part in parts: elements = part.split() key = elements[0] if len(elements) < 2: raise ParseError("KernPairs key without data: %s" % repr(line)) else: elements = elements[1:] data = " ".join(elements) try: if key == "KP": key = ( elements[0], elements[1], ) value = ( "KP", float(elements[2]), float(elements[3]), ) elif key == "KPH": key = ( ps_hex_int(elements[0]), ps_hex_int(elements[1]), ) value = ( "KPH", float(elements[2]), float(elements[3]), ) elif "KPX": key = ( elements[0], elements[1], ) value = ( "KPX", float(elements[2]), 0, ) elif "KPY": key = ( elements[0], elements[1], ) value = ( "KPY", 0, float(elements[2]), ) else: raise ParseError("Unknown data key in KernPairs line %s" %\ repr(line)) self.set(key, value) except IndexError: msg = "Illegel number of data elements in KernPairs line %s" %\ repr(line) raise ParseError(msg)
def parse_line(self, line): """Parse a CharMetrics line info a dict as { 'KEY': info }""" line = line.strip() # get rid of eol characters parts = line.split(";") # split by the ;s parts = filter(lambda s: s != "", parts) # remove whitespace info = {} for part in parts: elements = part.split() key = elements[0] if len(elements) < 2: raise ParseError("CharMetrics key without data") else: elements = elements[1:] data = " ".join(elements) # For these codes see Adobe Font Metrics File Format Specification # 3d. edition, pp. 31ff (section 8). if key == "C": # character code info["C"] = int(data) info["CH"] = int(data) elif key == "CH": # character code (hex) data = ps_hex_int(data) info["C"] = data info["CH"] = data elif key == "WX" or key == "W0X": # character width direction 0 data = float(data) info["WX"] = data info["W0X"] = data elif key == "W1X": # character width direction 1 info["W1X"] = float(data) elif key == "WY" or key == "W0Y": # character height direction 0 data = float(data) info["WY"] = data info["W0Y"] = data elif key == "W1Y": # character height direction 1 info["W1Y"] = float(data) elif key == "W" or key == "W0": # character width vector (wri dir 0 wx, wy = float_pair(elements) info["W"] = ( wx, wy, ) info["W0"] = ( wx, wy, ) elif key == "W1": # character width vector (writing direction 1) wx, wy = float_pair(elements) info["W1"] = ( wx, wy, ) elif key == "W1": # character width vector (writing direction 1) wx, wy = float_pair(elements) info["W1"] = ( wx, wy, ) elif key == "N": # postscript character name info["N"] = data elif key == "B": # character bounding box info["B"] = float_tuple(elements, 4) elif key == "L": # Ligature if len(elements) != 2: raise ParseError( "CharMetrics key L must be L successor ligature") if "L" not in info: info["L"] = {} info["L"][elements[0]] = elements[1] else: raise ParseError("Unknown CharMetric line: %s" % repr(line)) if "C" not in info: raise ParseError("Illegal CharMetrics line: Either C or CH key" + "must be present! (%s)" % repr(line)) if info["C"] != -1: self[info["C"]] = info try: glyph_name = info["N"] if glyph_name != '.notdef': self.by_glyph_name[glyph_name] = info except KeyError: raise ParseError( "No glyph name specified for character code {}".format( info["C"]))
def parse(self, line_iterator, parent): while True: line = line_iterator.readline() if line == "": if self.implicit_keyword: break else: raise ParseError("Unexpected end of file") if line.strip() == "": # empty line continue parts = line.split() keyword = parts[0] if len(parts) > 1: info = " ".join(parts[1:]) else: info = "" if keyword in self.keywords.keywords(): self.add_keyword(keyword, info) elif keyword in self.subsections.start_keywords(): self.add_subsection(line_iterator, keyword, info) elif keyword.startswith("End%s" % self.__class__.__name__): return # Finished this section elif parent is not None and keyword in parent.keywords.keywords(): # It seems that if the subsection's keywords are omited # section and subsection keywords may be mixed freely. # No word of that in the specification but as Adobe's own # files do it, it must be "standard" complient, I guess. # This format suks. parent.add_keyword(keyword, info) elif parent is not None and keyword \ in parent.subsections.start_keywords(): parent.add_subsection(line_iterator, keyword, info) elif parent is not None and \ keyword.startswith("End%s" % parent.__class__.__name__): # We'v run into the parent's End line, rewind the file buffer # so that the parent sees the line and pass control back # to 'him'. line_iterator.rewind() return elif keyword in ( "", "Comment", ): continue # An empty line elif keyword[0] in "abcdefghijklmnopqrstuvwxyz": continue # keywords that start with a lower char are user # defined and supposed to be ignored else: # Check the subsection's keyword lists: If it is a keyword # from an implicit subsection rewind the filepointer to the # beginning of the line and create a new section. found = False for cls in self.subsections: if cls.implicit_start_stop and \ keyword in cls.keywords.keywords(): line_iterator.rewind() found = True self.add_subsection(line_iterator, cls.__name__, None, implicit_start_stop=True) if not found: tpl = ( self.__class__.__name__, repr(line), ) raise ParseError("Unknown line in %s section: %s " % tpl)
def __init__(self, value): try: py_float.__init__(self, value) except ValueError: raise ParseError("Illegal representation of a float: %s" % repr(value))
def __init__(self, value, base=10): try: py_int.__init__(self, value, base) except ValueError: raise ParseError("Illegal representation of an integer: %s" % repr(value))