diff --git a/ziffers/classes.py b/ziffers/classes.py index 3ba4d4f..1a241a4 100644 --- a/ziffers/classes.py +++ b/ziffers/classes.py @@ -112,6 +112,7 @@ class Chord(Event): """Set notes to the class""" self.notes = notes + @dataclass class RomanNumeral(Event): """Class for roman numbers""" @@ -228,17 +229,25 @@ class Ziffers(Sequence): key = self.options["key"] scale = self.options["scale"] if isinstance(self.current, (Pitch, RandomPitch)): - note = note_from_pc(root=key,pitch_class=self.current.pitch_class,intervals=scale,modifier=self.current.modifier) + note = note_from_pc( + root=key, + pitch_class=self.current.pitch_class, + intervals=scale, + modifier=self.current.modifier, + ) self.current.set_note(note) - elif isinstance(self.current,Chord): + elif isinstance(self.current, Chord): pcs = self.current.pitch_classes - notes = [pc.set_note(note_from_pc(key, pc.pitch_class, scale)) for pc in pcs] + notes = [ + pc.set_note(note_from_pc(key, pc.pitch_class, scale)) for pc in pcs + ] self.current.set_notes(notes) - elif isinstance(self.current,RomanNumeral): - pitch_classes = [midi_to_pitch_class(note, key, scale) for note in self.current.notes] + elif isinstance(self.current, RomanNumeral): + pitch_classes = [ + midi_to_pitch_class(note, key, scale) for note in self.current.notes + ] self.current.set_pitch_classes(pitch_classes) - self.loop_i += 1 return self.current @@ -342,13 +351,13 @@ class Cyclic(Sequence): wrap_end: str = field(default=">", repr=False) def __next__(self): - yield self.values[self.cycle%len(self.cycle)] - self.cycle+=1 + yield self.values[self.cycle % len(self.cycle)] + self.cycle += 1 raise StopIteration def value(self): """Get the value for the current cycle""" - return self.values[self.cycle%len(self.cycle)] + return self.values[self.cycle % len(self.cycle)] @dataclass diff --git a/ziffers/mapper.py b/ziffers/mapper.py index 40953d8..587ca54 100644 --- a/ziffers/mapper.py +++ b/ziffers/mapper.py @@ -37,7 +37,7 @@ from .scale import parse_roman, chord_from_roman_numeral class ZiffersTransformer(Transformer): """Rules for transforming Ziffers expressions into tree.""" - def __init__(self, options: Optional[dict]=None): + def __init__(self, options: Optional[dict] = None): super().__init__() self.options = options @@ -114,21 +114,27 @@ class ZiffersTransformer(Transformer): """Parses chord""" return Chord(pitch_classes=items, text="".join([val.text for val in items])) - def named_roman(self,items) -> RomanNumeral: + def named_roman(self, items) -> RomanNumeral: """Parse chord from roman numeral""" numeral = items[0].value - if len(items)>1: + if len(items) > 1: name = items[1] - chord_notes = chord_from_roman_numeral(numeral,name) + chord_notes = chord_from_roman_numeral(numeral, name) parsed_number = parse_roman(numeral) - return RomanNumeral(text=numeral, value=parsed_number, chord_type=name, notes=chord_notes) - return RomanNumeral(value=parse_roman(numeral), text=numeral, notes=chord_from_roman_numeral(numeral)) + return RomanNumeral( + text=numeral, value=parsed_number, chord_type=name, notes=chord_notes + ) + return RomanNumeral( + value=parse_roman(numeral), + text=numeral, + notes=chord_from_roman_numeral(numeral), + ) - def chord_name(self,item): + def chord_name(self, item): """Return name for chord""" return item[0].value - def roman_number(self,item): + def roman_number(self, item): """Return roman numeral""" return item.value @@ -147,7 +153,7 @@ class ZiffersTransformer(Transformer): val = val * (2.0 - (1.0 / (2 * dots))) chars = chars + (dchar + "." * dots) durs = durs + val - return {"text":chars, "duration":durs} + return {"text": chars, "duration": durs} def dchar_not_prefix(self, items): """Return partial duration char info""" @@ -222,9 +228,13 @@ class ZiffersTransformer(Transformer): val = items[0] return Eval(values=val) + def sub_operations(self, items): + """Returns list of operations""" + return Eval(values=items[0], wrap_start="(", wrap_end=")") + def operation(self, items): """Return partial eval operations""" - return items + return flatten(items) def atom(self, token): """Return partial eval item""" diff --git a/ziffers/ziffers.lark b/ziffers/ziffers.lark index e2c0f28..fe81493 100644 --- a/ziffers/ziffers.lark +++ b/ziffers/ziffers.lark @@ -18,7 +18,7 @@ ?roman_number: /iv|v|v?i{1,3}/ // Valid as integer - ?number: SIGNED_NUMBER | random_integer | cyclic_number + ?number: NUMBER | random_integer | cyclic_number cyclic_number: "<" number (WS number)* ">" // Repeats @@ -69,11 +69,12 @@ // Rules for evaluating clauses inside {} // TODO: Support for parenthesis? - eval: "{" operation "}" - operation: atom (operator atom)+ - atom: (number | DECIMAL) + eval: "{" operation+ "}" + operation: atom (operator (sub_operations | operation))* + sub_operations: "(" operation ")" + atom: (NUMBER | DECIMAL) %import common.NUMBER - %import common.SIGNED_NUMBER + //%import common.SIGNED_NUMBER %import common.DECIMAL %import common.WS \ No newline at end of file