6 from rational import Rational
9 def escape_instrument_string (input_string):
10 retstring = string.replace (input_string, "\"", "\\\"")
11 if re.match ('.*[\r\n]+.*', retstring):
12 rx = re.compile (r'[\n\r]+')
13 strings = rx.split (retstring)
14 retstring = "\\markup { \\column { "
16 retstring += "\\line {\"" + s + "\"} "
19 retstring = "\"" + retstring + "\""
22 class Output_stack_element:
24 self.factor = Rational (1)
26 o = Output_stack_element()
27 o.factor = self.factor
32 """A class that takes care of formatting (eg.: indenting) a
33 Music expression as a .ly file.
36 ## TODO: support for \relative.
42 self._file = sys.stdout
44 self._output_state_stack = [Output_stack_element()]
45 self._skipspace = False
46 self._last_duration = None
48 def set_file (self, file):
51 def dump_version (self):
53 self.print_verbatim ('\\version "@TOPLEVEL_VERSION@"')
56 def get_indent (self):
57 return self._nesting * self._indent
60 last = self._output_state_stack[-1]
61 self._output_state_stack.append (last.copy())
63 def add_factor (self, factor):
65 self._output_state_stack[-1].factor *= factor
68 del self._output_state_stack[-1]
69 if not self._output_state_stack:
72 def duration_factor (self):
73 return self._output_state_stack[-1].factor
75 def print_verbatim (self, str):
78 def unformatted_output (self, str):
79 # don't indent on \< and indent only once on <<
80 self._nesting += ( str.count ('<')
81 - str.count ('\<') - str.count ('<<')
83 self._nesting -= ( str.count ('>') - str.count ('\>') - str.count ('>>')
84 - str.count ('->') - str.count ('_>')
87 self.print_verbatim (str)
89 def print_duration_string (self, str):
90 if self._last_duration == str:
93 self.unformatted_output (str)
95 def add_word (self, str):
96 if (len (str) + 1 + len (self._line) > self._line_len):
98 self._skipspace = True
100 if not self._skipspace:
102 self.unformatted_output (str)
103 self._skipspace = False
106 self._file.write (self._line + '\n')
107 self._line = ' ' * self._indent * self._nesting
108 self._skipspace = True
110 def skipspace (self):
111 self._skipspace = True
113 def __call__(self, arg):
116 def dump (self, str):
118 self._skipspace = False
119 self.unformatted_output (str)
121 words = string.split (str)
134 self.duration_log = 0
136 self.factor = Rational (1)
138 def lisp_expression (self):
139 return '(ly:make-duration %d %d %d %d)' % (self.duration_log,
141 self.factor.numerator (),
142 self.factor.denominator ())
145 def ly_expression (self, factor = None):
149 str = '%d%s' % (1 << self.duration_log, '.'*self.dots)
151 if factor <> Rational (1,1):
152 if factor.denominator () <> 1:
153 str += '*%d/%d' % (factor.numerator (), factor.denominator ())
155 str += '*%d' % factor.numerator ()
159 def print_ly (self, outputter):
160 str = self.ly_expression (self.factor / outputter.duration_factor ())
161 outputter.print_duration_string (str)
164 return self.ly_expression()
169 d.duration_log = self.duration_log
170 d.factor = self.factor
173 def get_length (self):
174 dot_fact = Rational( (1 << (1 + self.dots))-1,
177 log = abs (self.duration_log)
179 if self.duration_log < 0:
180 base = Rational (dur)
182 base = Rational (1, dur)
184 return base * dot_fact * self.factor
194 return self.ly_expression()
196 def transposed (self, interval):
198 c.alteration += interval.alteration
199 c.step += interval.step
200 c.octave += interval.octave
203 target_st = self.semitones() + interval.semitones()
204 c.alteration += target_st - c.semitones()
211 c.octave += c.step / 7
214 def lisp_expression (self):
215 return '(ly:make-pitch %d %d %d)' % (self.octave,
221 p.alteration = self.alteration
223 p.octave = self.octave
227 return self.step + self.octave *7
229 def semitones (self):
230 return self.octave * 12 + [0,2,4,5,7,9,11][self.step] + self.alteration
232 def ly_step_expression (self):
233 str = 'cdefgab'[self.step]
234 if self.alteration > 0:
235 str += 'is'* (self.alteration)
236 elif self.alteration < 0:
237 str += 'es'* (-self.alteration)
239 return str.replace ('aes', 'as').replace ('ees', 'es')
241 def ly_expression (self):
242 str = self.ly_step_expression ()
244 str += "'" * (self.octave + 1)
245 elif self.octave < -1:
246 str += "," * (-self.octave - 1)
250 def print_ly (self, outputter):
251 outputter (self.ly_expression())
256 self.start = Rational (0)
258 self.identifier = None
260 def get_length(self):
263 def get_properties (self):
266 def has_children (self):
269 def get_index (self):
271 return self.parent.elements.index (self)
275 return self.__class__.__name__
277 def lisp_expression (self):
280 props = self.get_properties ()
282 return "(make-music '%s %s)" % (name, props)
284 def set_start (self, start):
287 def find_first (self, predicate):
292 def print_comment (self, printer, text = None):
303 lines = string.split (text, '\n')
306 printer.unformatted_output ('% ' + l)
310 def print_with_identifier (self, printer):
312 printer ("\\%s" % self.identifier)
314 self.print_ly (printer)
316 def print_ly (self, printer):
317 printer (self.ly_expression ())
319 class MusicWrapper (Music):
323 def print_ly (self, func):
324 self.element.print_ly (func)
326 class ModeChangingMusicWrapper (MusicWrapper):
328 MusicWrapper.__init__ (self)
329 self.mode = 'notemode'
331 def print_ly (self, func):
332 func ('\\%s' % self.mode)
333 MusicWrapper.print_ly (self, func)
335 class TimeScaledMusic (MusicWrapper):
336 def print_ly (self, func):
337 func ('\\times %d/%d ' %
338 (self.numerator, self.denominator))
339 func.add_factor (Rational (self.numerator, self.denominator))
340 MusicWrapper.print_ly (self, func)
343 class NestedMusic(Music):
345 Music.__init__ (self)
348 def append (self, what):
350 self.elements.append (what)
352 def has_children (self):
355 def insert_around (self, succ, elt, dir):
356 assert elt.parent == None
357 assert succ == None or succ in self.elements
362 idx = self.elements.index (succ)
369 idx = len (self.elements)
371 self.elements.insert (idx, elt)
374 def get_properties (self):
375 return ("'elements (list %s)"
376 % string.join (map (lambda x: x.lisp_expression(),
379 def get_subset_properties (self, predicate):
380 return ("'elements (list %s)"
381 % string.join (map (lambda x: x.lisp_expression(),
382 filter ( predicate, self.elements))))
383 def get_neighbor (self, music, dir):
384 assert music.parent == self
385 idx = self.elements.index (music)
387 idx = min (idx, len (self.elements) -1)
390 return self.elements[idx]
392 def delete_element (self, element):
393 assert element in self.elements
395 self.elements.remove (element)
396 element.parent = None
398 def set_start (self, start):
400 for e in self.elements:
403 def find_first (self, predicate):
404 r = Music.find_first (self, predicate)
408 for e in self.elements:
409 r = e.find_first (predicate)
414 class SequentialMusic (NestedMusic):
415 def get_last_event_chord (self):
417 at = len( self.elements ) - 1
419 not isinstance (self.elements[at], EventChord) and
420 not isinstance (self.elements[at], BarLine)):
423 if (at >= 0 and isinstance (self.elements[at], EventChord)):
424 value = self.elements[at]
427 def print_ly (self, printer, newline = True):
430 self.print_comment (printer)
434 for e in self.elements:
441 def lisp_sub_expression (self, pred):
445 props = self.get_subset_properties (pred)
447 return "(make-music '%s %s)" % (name, props)
449 def set_start (self, start):
450 for e in self.elements:
452 start += e.get_length()
456 self.repeat_type = "volta"
457 self.repeat_count = 2
460 def set_music (self, music):
461 if isinstance (music, Music):
463 elif isinstance (music, list):
464 self.music = SequentialMusic ()
465 self.music.elements = music
467 sys.stderr.write ("WARNING: Unable to set the music %s for the repeat %s" % (music, self))
468 def add_ending (self, music):
469 self.endings.append (music)
470 def print_ly (self, printer):
471 printer.dump ('\\repeat %s %s' % (self.repeat_type, self.repeat_count))
473 self.music.print_ly (printer)
475 sys.stderr.write ("WARNING: Encountered repeat without body\n")
478 printer.dump ('\\alternative {')
479 for e in self.endings:
486 self.lyrics_syllables = []
488 def print_ly (self, printer):
489 printer.dump ("\lyricmode {")
490 for l in self.lyrics_syllables:
491 printer.dump ( "%s " % l )
494 def ly_expression (self):
495 lstr = "\lyricmode {\n "
496 for l in self.lyrics_syllables:
504 self.header_fields = {}
505 def set_field (self, field, value):
506 self.header_fields[field] = value
508 def print_ly (self, printer):
509 printer.dump ("\header {")
511 for (k,v) in self.header_fields.items ():
513 printer.dump ('%s = %s' % (k,v))
522 class EventChord (NestedMusic):
524 NestedMusic.__init__ (self)
525 self.grace_elements = None
526 self.grace_type = None
527 def append_grace (self, element):
529 if not self.grace_elements:
530 self.grace_elements = SequentialMusic ()
531 self.grace_elements.append (element)
533 def get_length (self):
535 for e in self.elements:
536 l = max(l, e.get_length())
539 def print_ly (self, printer):
540 note_events = [e for e in self.elements if
541 isinstance (e, NoteEvent)]
543 rest_events = [e for e in self.elements if
544 isinstance (e, RhythmicEvent)
545 and not isinstance (e, NoteEvent)]
547 other_events = [e for e in self.elements if
548 not isinstance (e, RhythmicEvent)]
550 if self.grace_elements and self.elements:
552 printer ('\\%s' % self.grace_type)
555 # don't print newlines after the { and } braces
556 self.grace_elements.print_ly (printer, False)
559 rest_events[0].print_ly (printer)
560 elif len (note_events) == 1:
561 note_events[0].print_ly (printer)
563 pitches = [x.pitch.ly_expression () for x in note_events]
564 printer ('<%s>' % string.join (pitches))
565 note_events[0].duration.print_ly (printer)
569 for e in other_events:
572 self.print_comment (printer)
574 class Partial (Music):
576 Music.__init__ (self)
578 def print_ly (self, printer):
580 printer.dump ("\\partial %s" % self.partial.ly_expression ())
582 class BarLine (Music):
584 Music.__init__ (self)
588 def print_ly (self, printer):
589 bar_symbol = { 'regular': "|", 'dotted': ":", 'dashed': ":",
590 'heavy': "|", 'light-light': "||", 'light-heavy': "|.",
591 'heavy-light': ".|", 'heavy-heavy': ".|.", 'tick': "'",
592 'short': "'", 'none': "" }.get (self.type, None)
593 if bar_symbol <> None:
594 printer.dump ('\\bar "%s"' % bar_symbol)
598 if self.bar_number > 0 and (self.bar_number % 10) == 0:
599 printer.dump ("\\barNumberCheck #%d " % self.bar_number)
601 printer.print_verbatim (' %% %d' % self.bar_number)
604 def ly_expression (self):
610 class SpanEvent (Event):
612 Event.__init__ (self)
613 self.span_direction = 0 # start/stop
614 self.line_type = 'solid'
615 self.span_type = 0 # e.g. cres/decrescendo, ottava up/down
616 self.size = 0 # size of e.g. ocrave shift
617 def wait_for_note (self):
619 def get_properties(self):
620 return "'span-direction %d" % self.span_direction
621 def set_span_type (self, type):
622 self.span_type = type
624 class SlurEvent (SpanEvent):
625 def ly_expression (self):
628 # TODO: setting dashed/dotted line style does not work, because that
629 # command needs to be written before the note, not when the
630 # event is observed after the note!
631 #before = {'dotted': '\\slurDotted',
632 # 'dashed' : '\\slurDashed'}.get (self.line_type, '')
634 #after = '\\slurSolid'
636 return {-1: before + '(' + after,
637 1:')'}.get (self.span_direction, '')
639 class BeamEvent (SpanEvent):
640 def ly_expression (self):
642 1:']'}.get (self.span_direction, '')
644 class PedalEvent (SpanEvent):
645 def ly_expression (self):
646 return {-1: '\\sustainDown',
647 1:'\\sustainUp'}.get (self.span_direction, '')
649 # type==-1 means octave up, type==-2 means octave down
650 class OctaveShiftEvent (SpanEvent):
651 def wait_for_note (self):
653 def set_span_type (self, type):
654 self.span_type = {'up': 1, 'down': -1}.get (type, 0)
655 def ly_octave_shift_indicator (self):
656 # convert 8/15 to lilypond indicators (+-1/+-2)
657 value = {8: 1, 15: 2}.get (self.size, 0)
658 # negative values go up!
659 value *= -1*self.span_type
661 def ly_expression (self):
662 dir = self.ly_octave_shift_indicator ()
665 value = '#(set-octavation %s)' % dir
668 1: '#(set-octavation 0)'}.get (self.span_direction, '')
670 class TrillSpanEvent (SpanEvent):
671 def ly_expression (self):
672 return {-1: '\\startTrillSpan',
673 0: '', # no need to write out anything for type='continue'
674 1:'\\stopTrillSpan'}.get (self.span_direction, '')
676 class GlissandoEvent (SpanEvent):
677 def ly_expression (self):
679 # TODO: wavy-line glissandos don't work, becasue the style has to be
680 # set before the note, at the \glissando it's already too late!
681 #if self.line_type == 'wavy':
682 #style = "\once\override Glissando #'style = #'zigzag"
683 # In lilypond, glissando is NOT a spanner, unlike MusicXML.
684 return {-1: style + '\\glissando',
685 1:''}.get (self.span_direction, '')
687 class ArpeggioEvent(Event):
689 Event.__init__ (self)
691 def wait_for_note (self):
693 def ly_expression (self):
694 # TODO: Use self.direction for up/down arpeggios
695 return ('\\arpeggio')
698 class TieEvent(Event):
699 def ly_expression (self):
703 class HairpinEvent (SpanEvent):
704 def set_span_type (self, type):
705 self.span_type = {'crescendo' : 1, 'decrescendo' : -1, 'diminuendo' : -1 }.get (type, 0)
706 def hairpin_to_ly (self):
707 if self.span_direction == 1:
710 return {1: '\<', -1: '\>'}.get (self.span_type, '')
712 def ly_expression (self):
713 return self.hairpin_to_ly ()
715 def print_ly (self, printer):
716 val = self.hairpin_to_ly ()
722 class DynamicsEvent (Event):
725 self.available_commands = [ "ppppp", "pppp", "ppp", "pp", "p",
727 "f", "ff", "fff", "ffff",
728 "fp", "sf", "sff", "sp", "spp", "sfz", "rfz" ];
729 def wait_for_note (self):
731 def ly_expression (self):
732 if self.type == None:
734 elif self.type in self.available_commands:
735 return '\%s' % self.type
737 return '-\markup{ \dynamic %s }' % self.type
739 def print_ly (self, printer):
740 if self.type == None:
742 elif self.type in self.available_commands:
743 printer.dump ("\\%s" % self.type)
745 printer.dump ("-\\markup{ \\dynamic %s }" % self.type)
748 class TextEvent (Event):
751 self.force_direction = None
753 def wait_for_note (self):
756 def direction_mod (self):
757 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
759 def ly_expression (self):
760 base_string = '%s\"%s\"'
762 base_string = '%s\markup{ ' + self.markup + ' {%s} }'
763 return base_string % (self.direction_mod (), self.text)
765 class ArticulationEvent (Event):
768 self.force_direction = None
769 def wait_for_note (self):
772 def direction_mod (self):
773 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '')
775 def ly_expression (self):
776 return '%s\\%s' % (self.direction_mod (), self.type)
778 class ShortArticulationEvent (ArticulationEvent):
779 def direction_mod (self):
781 return { 1: '^', -1: '_', 0: '-' }.get (self.force_direction, '-')
782 def ly_expression (self):
784 return '%s%s' % (self.direction_mod (), self.type)
788 class NoDirectionArticulationEvent (ArticulationEvent):
789 def ly_expression (self):
791 return '\\%s' % self.type
795 class MarkupEvent (ShortArticulationEvent):
797 ArticulationEvent.__init__ (self)
799 def ly_expression (self):
801 return "%s\\markup { %s }" % (self.direction_mod (), self.contents)
805 class FretEvent (MarkupEvent):
807 MarkupEvent.__init__ (self)
808 self.force_direction = 1
813 def ly_expression (self):
815 if self.strings <> 6:
816 val += "w:%s;" % self.strings
818 val += "h:%s;" % self.frets
819 if self.barre and len (self.barre) >= 3:
820 val += "c:%s-%s-%s;" % (self.barre[0], self.barre[1], self.barre[2])
821 have_fingering = False
822 for i in self.elements:
824 val += "%s-%s" % (i[0], i[1])
826 have_fingering = True
832 return "%s\\markup { \\fret-diagram #\"%s\" }" % (self.direction_mod (), val)
836 class TremoloEvent (ArticulationEvent):
838 Event.__init__ (self)
841 def ly_expression (self):
843 if self.bars and self.bars > 0:
844 str += ':%s' % (2 ** (2 + string.atoi (self.bars)))
847 class BendEvent (ArticulationEvent):
849 Event.__init__ (self)
851 def ly_expression (self):
853 return "-\\bendAfter #%s" % self.alter
857 class RhythmicEvent(Event):
859 Event.__init__ (self)
860 self.duration = Duration()
862 def get_length (self):
863 return self.duration.get_length()
865 def get_properties (self):
866 return ("'duration %s"
867 % self.duration.lisp_expression ())
869 class RestEvent (RhythmicEvent):
871 RhythmicEvent.__init__ (self)
873 def ly_expression (self):
875 return "%s%s\\rest" % (self.pitch.ly_expression (), self.duration.ly_expression ())
877 return 'r%s' % self.duration.ly_expression ()
879 def print_ly (self, printer):
881 self.pitch.print_ly (printer)
882 self.duration.print_ly (printer)
886 self.duration.print_ly (printer)
888 class SkipEvent (RhythmicEvent):
889 def ly_expression (self):
890 return 's%s' % self.duration.ly_expression ()
892 class NoteEvent(RhythmicEvent):
894 RhythmicEvent.__init__ (self)
896 self.drum_type = None
897 self.cautionary = False
898 self.forced_accidental = False
900 def get_properties (self):
901 str = RhythmicEvent.get_properties (self)
904 str += self.pitch.lisp_expression ()
906 str += "'drum-type '%s" % self.drum_type
910 def pitch_mods (self):
914 if self.forced_accidental:
919 def ly_expression (self):
921 return '%s%s%s' % (self.pitch.ly_expression (),
923 self.duration.ly_expression ())
925 return '%s%s' (self.drum_type,
926 self.duration.ly_expression ())
928 def print_ly (self, printer):
930 self.pitch.print_ly (printer)
931 printer (self.pitch_mods ())
933 printer (self.drum_type)
935 self.duration.print_ly (printer)
937 class KeySignatureChange (Music):
939 Music.__init__ (self)
944 def ly_expression (self):
945 return '\\key %s \\%s' % (self.tonic.ly_step_expression (),
948 def lisp_expression (self):
949 pairs = ['(%d . %d)' % (i , self.scale[i]) for i in range (0,7)]
950 scale_str = ("'(%s)" % string.join (pairs))
952 return """ (make-music 'KeyChangeEvent
953 'pitch-alist %s) """ % scale_str
955 class TimeSignatureChange (Music):
957 Music.__init__ (self)
958 self.fraction = (4,4)
959 def ly_expression (self):
960 return '\\time %d/%d ' % self.fraction
962 class ClefChange (Music):
964 Music.__init__ (self)
969 def octave_modifier (self):
970 return {1: "^8", 2: "^15", -1: "_8", -2: "_15"}.get (self.octave, '')
971 def clef_name (self):
972 return {('G', 2): "treble",
975 ('C', 2): "mezzosoprano",
978 ('C', 5): "baritone",
979 ('F', 3): "varbaritone",
982 ("percussion", 2): "percussion",
983 ("TAB", 5): "tab"}.get ((self.type, self.position), None)
984 def ly_expression (self):
985 return '\\clef "%s%s"' % (self.clef_name (), self.octave_modifier ())
988 "G": ("clefs.G", -2, -6),
989 "C": ("clefs.C", 0, 0),
990 "F": ("clefs.F", 2, 6),
993 def lisp_expression (self):
995 (glyph, pos, c0) = self.clef_dict[self.type]
999 (make-music 'SequentialMusic
1002 (make-property-set 'clefGlyph "%s") 'Staff)
1004 (make-property-set 'clefPosition %d) 'Staff)
1006 (make-property-set 'middleCPosition %d) 'Staff)))
1007 """ % (glyph, pos, c0)
1011 class StaffChange (Music):
1012 def __init__ (self, staff):
1013 Music.__init__ (self)
1015 def ly_expression (self):
1017 return "\\change Staff=\"%s\"" % self.staff
1022 class MultiMeasureRest(Music):
1024 def lisp_expression (self):
1027 'MultiMeasureRestMusicGroup
1029 (list (make-music (quote BarCheck))
1034 'MultiMeasureRestEvent
1037 (make-music (quote BarCheck))))
1038 """ % self.duration.lisp_expression ()
1040 def ly_expression (self):
1041 return 'R%s' % self.duration.ly_expression ()
1045 def __init__ (self, command = "StaffGroup"):
1046 self.stafftype = command
1048 self.instrument_name = None
1049 self.short_instrument_name = None
1053 self.is_group = True
1054 # part_information is a list with entries of the form
1055 # [staffid, voicelist]
1056 # where voicelist is a list with entries of the form
1057 # [voiceid1, [lyricsid11, lyricsid12,...] ]
1058 self.part_information = None
1060 def append_staff (self, staff):
1061 self.children.append (staff)
1063 def set_part_information (self, part_name, staves_info):
1064 if part_name == self.id:
1065 self.part_information = staves_info
1067 for c in self.children:
1068 c.set_part_information (part_name, staves_info)
1070 def print_ly_contents (self, printer):
1071 for c in self.children:
1073 c.print_ly (printer)
1074 def print_ly_overrides (self, printer):
1076 needs_with |= self.spanbar == "no"
1077 needs_with |= self.instrument_name != None
1078 needs_with |= self.short_instrument_name != None
1079 needs_with |= (self.symbol != None) and (self.symbol != "bracket")
1081 printer.dump ("\\with {")
1082 if self.instrument_name or self.short_instrument_name:
1083 printer.dump ("\\consists \"Instrument_name_engraver\"")
1084 if self.spanbar == "no":
1085 printer.dump ("\\override SpanBar #'transparent = ##t")
1086 brack = {"brace": "SystemStartBrace",
1088 "line": "SystemStartSquare"}.get (self.symbol, None)
1090 printer.dump ("systemStartDelimiter = #'%s" % brack)
1093 def print_ly (self, printer):
1095 printer.dump ("\\new %s" % self.stafftype)
1096 self.print_ly_overrides (printer)
1099 if self.stafftype and self.instrument_name:
1100 printer.dump ("\\set %s.instrumentName = %s" % (self.stafftype,
1101 escape_instrument_string (self.instrument_name)))
1103 if self.stafftype and self.short_instrument_name:
1104 printer.dump ("\\set %s.shortInstrumentName = %s" % (self.stafftype,
1105 escape_instrument_string (self.short_instrument_name)))
1107 self.print_ly_contents (printer)
1113 class Staff (StaffGroup):
1114 def __init__ (self, command = "Staff"):
1115 StaffGroup.__init__ (self, command)
1116 self.is_group = False
1118 self.voice_command = "Voice"
1119 self.substafftype = None
1121 def print_ly_overrides (self, printer):
1124 def print_ly_contents (self, printer):
1125 if not self.id or not self.part_information:
1127 sub_staff_type = self.substafftype
1128 if not sub_staff_type:
1129 sub_staff_type = self.stafftype
1131 for [staff_id, voices] in self.part_information:
1133 printer ('\\context %s = "%s" << ' % (sub_staff_type, staff_id))
1135 printer ('\\context %s << ' % sub_staff_type)
1138 nr_voices = len (voices)
1139 for [v, lyrics] in voices:
1141 voice_count_text = ''
1143 voice_count_text = {1: ' \\voiceOne', 2: ' \\voiceTwo',
1144 3: ' \\voiceThree'}.get (n, ' \\voiceFour')
1145 printer ('\\context %s = "%s" {%s \\%s }' % (self.voice_command, v, voice_count_text, v))
1149 printer ('\\new Lyrics \\lyricsto "%s" \\%s' % (v,l))
1153 def print_ly (self, printer):
1154 if self.part_information and len (self.part_information) > 1:
1155 self.stafftype = "PianoStaff"
1156 self.substafftype = "Staff"
1157 StaffGroup.print_ly (self, printer)
1159 class TabStaff (Staff):
1160 def __init__ (self, command = "TabStaff"):
1161 Staff.__init__ (self, command)
1162 self.string_tunings = []
1163 self.tablature_format = None
1164 self.voice_command = "TabVoice"
1165 def print_ly_overrides (self, printer):
1166 if self.string_tunings or self.tablature_format:
1167 printer.dump ("\\with {")
1168 if self.string_tunings:
1169 printer.dump ("stringTunings = #'(")
1170 for i in self.string_tunings:
1171 printer.dump ("%s" % i.semitones ())
1173 if self.tablature_format:
1174 printer.dump ("tablatureFormat = #%s" % self.tablature_format)
1178 class DrumStaff (Staff):
1179 def __init__ (self, command = "DrumStaff"):
1180 Staff.__init__ (self, command)
1181 self.drum_style_table = None
1182 self.voice_command = "DrumVoice"
1183 def print_ly_overrides (self, printer):
1184 if self.drum_style_table:
1185 printer.dump ("\with {")
1186 printer.dump ("drumStyleTable = #%s" % self.drum_style_table)
1189 class RhythmicStaff (Staff):
1190 def __init__ (self, command = "RhythmicStaff"):
1191 Staff.__init__ (self, command)
1196 bflat.alteration = -1
1206 print bflat.semitones()
1207 print bflat.transposed (fifth), bflat.transposed (fifth).transposed (fifth)
1208 print bflat.transposed (fifth).transposed (fifth).transposed (fifth)
1210 print bflat.semitones(), 'down'
1211 print bflat.transposed (down)
1212 print bflat.transposed (down).transposed (down)
1213 print bflat.transposed (down).transposed (down).transposed (down)
1217 def test_printer ():
1225 m = SequentialMusic()
1226 m.append (make_note ())
1227 m.append (make_note ())
1228 m.append (make_note ())
1231 t = TimeScaledMusic ()
1237 m = SequentialMusic ()
1238 m.append (make_tup ())
1239 m.append (make_tup ())
1240 m.append (make_tup ())
1242 printer = Output_printer()
1243 m.print_ly (printer)
1247 m = SequentialMusic()
1251 n.duration.duration_log = l
1253 evc.insert_around (None, n, 0)
1254 m.insert_around (None, evc, 0)
1258 n.duration.duration_log = l
1260 evc.insert_around (None, n, 0)
1261 m.insert_around (None, evc, 0)
1265 n.duration.duration_log = l
1267 evc.insert_around (None, n, 0)
1268 m.insert_around (None, evc, 0)
1272 m.insert_around (None, evc, 0)
1277 tonic.alteration = -2
1278 n = KeySignatureChange()
1279 n.tonic=tonic.copy()
1280 n.scale = [0, 0, -2, 0, 0,-2,-2]
1282 evc.insert_around (None, n, 0)
1283 m.insert_around (None, evc, 0)
1288 if __name__ == '__main__':
1294 expr.set_start (Rational (0))
1295 print expr.ly_expression()
1296 start = Rational (0,4)
1297 stop = Rational (4,2)
1298 def sub(x, start=start, stop=stop):
1299 ok = x.start >= start and x.start +x.get_length() <= stop
1302 print expr.lisp_sub_expression(sub)