def parse_meta(self, lines): self.meta = OrderedDict() for key, val in self.keyvalues(lines): lang = None m = re.match(r"(.*)\[(.*)\]", key) if m: key = m.group(1) lang = m.group(2) if key not in self.meta: self.meta[key] = MultiString() self.meta[key][lang] = val
def parse_twolevel(self, lines): inner = None for line in lines: if not line: continue if line[0] == "{": if line[-1] != "}": raise ParseError("Expected {...} (%s)" % line) if inner is not None: yield name, inner name = line[1:-1] inner = OrderedDict() continue if inner is None: raise ParseError("Expected {...} (%s)" % line) if "=" not in line: raise ParseError("Expected key=value format (%s)" % line) key, val = line.split("=", 1) inner[key] = val if inner is not None: yield name, inner
def parse_variants(self, lines): self.variants = OrderedDict() for name, data in self.parse_twolevel(lines): self.variants[name] = Variant(data)
def parse_styles(self, lines): self.styles = OrderedDict() for name, data in self.parse_twolevel(lines): self.styles[name] = Style(data)
def parse_formats(self, lines): self.formats = OrderedDict() for tag, fmt in self.keyvalues(lines): if fmt not in FORMATS: raise ParseError("Unknown format %s" % fmt) self.formats[tag] = FORMATS[fmt]
def parse_song(self, lines): self.song = OrderedDict() for key, val in self.keyvalues(lines): self.song[key] = val
def __init__(self, filename=None, ignore_steps=False): parsers = { "Meta": self.parse_meta, "Song": self.parse_song, "Timing": self.parse_timing, "Formats": self.parse_formats, "Styles": self.parse_styles, "Variants": self.parse_variants, "Lyrics": self.parse_lyrics, } self.ignore_steps = ignore_steps self.pathbase = os.path.dirname(filename) if filename else None section = None lines = [] self.meta = None self.song = None self.timing = None self.formats = None self.styles = None self.variants = None self.compounds = None self.fake_time = 0 self.line = 0 self.section_line = 0 if not filename: self.meta = OrderedDict() self.song = OrderedDict() self.timing = BeatCounter() self.formats = OrderedDict() self.styles = OrderedDict() self.variants = OrderedDict() self.compounds = [] return for line in codecs.open(filename, encoding='utf-8', mode='r'): self.line += 1 line = line.replace("\n","").replace("\r","") if line.startswith("#"): continue if section is None: if not line: continue if line[0] != "[" or line[-1] != "]": raise ParseError("Expected section header") section = line[1:-1] self.section_line = self.line continue if line and line[0] == "[" and line[-1] == "]": if section not in parsers: raise ParseError("Unknown section %s" % section) parsers[section](lines) lines = [] section = line[1:-1] self.section_line = self.line else: lines.append(line) if section is not None: parsers[section](lines) if self.variants and self.styles: for variant in self.variants.values(): variant.load_tags(self.styles)