Пример #1
0
 def _set_duration(self, new_duration, repeat_ties=False):
     import abjad
     new_duration = Duration(new_duration)
     # change LilyPond multiplier if leaf already has LilyPond multiplier
     if self._get_indicators(Multiplier):
         detach(Multiplier, self)
         multiplier = new_duration.__div__(self.written_duration)
         attach(multiplier, self)
         return select(self)
     # change written duration if new duration is assignable
     try:
         self.written_duration = new_duration
         return select(self)
     except AssignabilityError:
         pass
     # make new notes or tuplets if new duration is nonassignable
     maker = abjad.NoteMaker(repeat_ties=repeat_ties, )
     components = maker(0, new_duration)
     if isinstance(components[0], abjad.Leaf):
         tied_leaf_count = len(components) - 1
         tied_leaves = tied_leaf_count * self
         all_leaves = [self] + tied_leaves
         for leaf, component in zip(all_leaves, components):
             leaf.written_duration = component.written_duration
         self._splice(tied_leaves, grow_spanners=True)
         parentage = abjad.inspect(self).get_parentage()
         if not abjad.inspect(parentage).get_spanners(abjad.Tie):
             tie = abjad.Tie()
             if tie._attachment_test(self):
                 tie = abjad.Tie(repeat=repeat_ties)
                 attach(tie, all_leaves)
         return select(all_leaves)
     else:
         assert isinstance(components[0], abjad.Tuplet)
         tuplet = components[0]
         components = tuplet[:]
         tied_leaf_count = len(components) - 1
         tied_leaves = tied_leaf_count * self
         all_leaves = [self] + tied_leaves
         for leaf, component in zip(all_leaves, components):
             leaf.written_duration = component.written_duration
         self._splice(tied_leaves, grow_spanners=True)
         if not self._get_spanners(abjad.Tie):
             tie = abjad.Tie()
             if tie._attachment_test(self):
                 tie = abjad.Tie(repeat=repeat_ties)
                 attach(tie, all_leaves)
         multiplier = tuplet.multiplier
         tuplet = abjad.Tuplet(multiplier, [])
         abjad.mutate(all_leaves).wrap(tuplet)
         return select(tuplet)
Пример #2
0
 def _at_least_two_leaves(self, argument):
     leaves = select(argument).leaves()
     if 1 < len(leaves):
         return True
     return [
         'Requires at least two leaves.',
         f'Not just {leaves[0]!r}.',
     ]
Пример #3
0
 def leaves(self) -> Selection:
     r'''Gets leaves in spanner.
     '''
     for leaf in self._leaves:
         if not isinstance(leaf, Leaf):
             message = f'spanners attach only to leaves (not {leaf!s}).'
             raise Exception(message)
     return select(self._leaves)
Пример #4
0
    def __getitem__(self, argument):
        r'''Gets item or slice identified by `argument`.

        Returns leaf.
        '''
        if isinstance(argument, slice):
            leaves = self.leaves.__getitem__(argument)
            return select(leaves)
        return self.leaves.__getitem__(argument)
Пример #5
0
 def previous(component):
     new_component = component._get_nth_component_in_time_order_from(-1)
     if new_component is None:
         return
     candidates = new_component._get_descendants_stopping_with()
     candidates = [x for x in candidates if isinstance(x, abjad.Leaf)]
     for candidate in candidates:
         selection = select([component, candidate])
         if selection.are_logical_voice():
             return candidate
Пример #6
0
 def _extend(self, leaves):
     leaf_input = list(self[-1:])
     leaf_input.extend(leaves)
     leaf_input = select(leaf_input)
     if self._contiguity_constraint == 'logical voice':
         if not leaf_input.are_contiguous_logical_voice():
             message = f'{self!r} leaves must be contiguous:\n'
             message += f'  {leaf_input}'
             raise Exception(message)
     for leaf in leaves:
         self._append(leaf)
Пример #7
0
 def _initialize_rhythm(self, rhythm):
     import abjad
     if isinstance(rhythm, abjad.Component):
         selection = select([rhythm])
     elif isinstance(rhythm, abjad.Selection):
         selection = rhythm
     else:
         message = 'rhythm must be duration, component or selection: {!r}.'
         message = message.format(rhythm)
         raise TypeError(message)
     assert isinstance(selection, abjad.Selection)
     return selection
Пример #8
0
 def _append(self, leaf):
     if self._ignore_attachment_test:
         pass
     elif not self._attachment_test(leaf):
         message = f'can not attach {self!r} to {leaf!r}.'
         raise Exception(message)
     if self._contiguity_constraint == 'logical voice':
         leaves = self[-1:] + [leaf]
         leaves = select(leaves)
         if not leaves.are_contiguous_logical_voice():
             raise Exception(type(self), leaves)
     leaf._append_spanner(self)
     self._leaves.append(leaf)
Пример #9
0
    def attach_defaults(self, argument) -> typing.List:
        r'''Attaches defaults to all staff and staff group contexts in
        ``argument`` when ``argument`` is a score.

        Attaches defaults to ``argument`` (without iterating ``argument``) when
        ``argument`` is a staff or staff group.

        Returns list of one wrapper for every indicator attached.
        '''
        assert isinstance(argument, (Score, Staff, StaffGroup)), repr(argument)
        wrappers: typing.List[Wrapper] = []
        tag = Tags().REMOVE_ALL_EMPTY_STAVES
        empty_prototype = (MultimeasureRest, Skip)
        prototype = (Staff, StaffGroup)
        if isinstance(argument, Score):
            staff__groups = select(argument).components(prototype)
            staves = select(argument).components(Staff)
        elif isinstance(argument, Staff):
            staff__groups = [argument]
            staves = [argument]
        else:
            assert isinstance(argument, StaffGroup), repr(argument)
            staff__groups = [argument]
            staves = []
        for staff__group in staff__groups:
            leaf = None
            voices = select(staff__group).components(Voice)
            # find first leaf in first nonempty voice
            for voice in voices:
                leaves = select(voice).leaves()
                if not all(isinstance(_, empty_prototype) for _ in leaves):
                    leaf = inspect(voice).get_leaf(0)
            # otherwise, find first leaf in voice in non-removable staff
            if leaf is None:
                for voice in voices:
                    voice_might_vanish = False
                    for component in inspect(voice).get_parentage():
                        if inspect(component).get_annotation(tag) is True:
                            voice_might_vanish = True
                    if not voice_might_vanish:
                        leaf = inspect(voice).get_leaf(0)
                        if leaf is not None:
                            break
            # otherwise, as last resort find first leaf in first voice
            if leaf is None:
                leaf = inspect(voices[0]).get_leaf(0)
            if leaf is None:
                continue
            instrument = inspect(leaf).get_indicator(Instrument)
            if instrument is None:
                string = 'default_instrument'
                instrument = inspect(staff__group).get_annotation(string)
                if instrument is not None:
                    wrapper = attach(instrument, leaf, tag='ST1', wrapper=True)
                    wrappers.append(wrapper)
            margin_markup = inspect(leaf).get_indicator(MarginMarkup)
            if margin_markup is None:
                string = 'default_margin_markup'
                margin_markup = inspect(staff__group).get_annotation(string)
                if margin_markup is not None:
                    wrapper = attach(
                        margin_markup,
                        leaf,
                        tag=Tag('-PARTS').prepend('ST2'),
                        wrapper=True,
                    )
                    wrappers.append(wrapper)
        for staff in staves:
            leaf = inspect(staff).get_leaf(0)
            clef = inspect(leaf).get_indicator(Clef)
            if clef is not None:
                continue
            clef = inspect(staff).get_annotation('default_clef')
            if clef is not None:
                wrapper = attach(clef, leaf, tag='ST3', wrapper=True)
                wrappers.append(wrapper)
        return wrappers
Пример #10
0
 def _split_by_durations(
     self,
     durations,
     cyclic=False,
     fracture_spanners=False,
     tie_split_notes=True,
     repeat_ties=False,
 ):
     import abjad
     durations = [Duration(_) for _ in durations]
     durations = abjad.sequence(durations)
     leaf_duration = abjad.inspect(self).get_duration()
     if cyclic:
         durations = durations.repeat_to_weight(leaf_duration)
     if sum(durations) < leaf_duration:
         last_duration = leaf_duration - sum(durations)
         durations = list(durations)
         durations.append(last_duration)
         durations = abjad.sequence(durations)
     durations = durations.truncate(weight=leaf_duration)
     result_selections = []
     # detach grace containers
     grace_container = self._detach_grace_container()
     after_grace_container = self._detach_after_grace_container()
     leaf_prolation = abjad.inspect(self).get_parentage().prolation
     for duration in durations:
         new_leaf = copy.copy(self)
         preprolated_duration = duration / leaf_prolation
         selection = new_leaf._set_duration(
             preprolated_duration,
             repeat_ties=repeat_ties,
         )
         result_selections.append(selection)
     result_components = abjad.sequence(result_selections).flatten(depth=-1)
     result_components = select(result_components)
     result_leaves = select(result_components).leaves()
     assert all(isinstance(_, abjad.Selection) for _ in result_selections)
     assert all(isinstance(_, Component) for _ in result_components)
     assert result_leaves.are_leaves()
     if abjad.inspect(self).has_spanner(abjad.Tie):
         for leaf in result_leaves:
             detach(abjad.Tie, leaf)
     # strip result leaves of indicators (other than multipliers)
     for leaf in result_leaves:
         multiplier = abjad.inspect(leaf).get_indicator(Multiplier)
         detach(object, leaf)
         if multiplier is not None:
             attach(multiplier, leaf)
     # replace leaf with flattened result
     selection = select(self)
     parent, start, stop = selection._get_parent_and_start_stop_indices()
     if parent:
         parent.__setitem__(slice(start, stop + 1), result_components)
     else:
         selection._give_dominant_spanners(result_components)
         selection._withdraw_from_crossing_spanners()
     # fracture spanners
     if fracture_spanners:
         first_selection = result_selections[0]
         for spanner in abjad.inspect(first_selection[-1]).get_spanners():
             index = spanner._index(first_selection[-1])
             spanner._fracture(index, direction=abjad.Right)
         last_selection = result_selections[-1]
         for spanner in abjad.inspect(last_selection[0]).get_spanners():
             index = spanner._index(last_selection[0])
             spanner._fracture(index, direction=abjad.Left)
         for middle_selection in result_selections[1:-1]:
             spanners = abjad.inspect(middle_selection[0]).get_spanners()
             for spanner in spanners:
                 index = spanner._index(middle_selection[0])
                 spanner._fracture(index, direction=abjad.Left)
             spanners = abjad.inspect(middle_selection[-1]).get_spanners()
             for spanner in spanners:
                 index = spanner._index(middle_selection[-1])
                 spanner._fracture(index, direction=abjad.Right)
     # move indicators
     first_result_leaf = result_leaves[0]
     last_result_leaf = result_leaves[-1]
     for indicator in abjad.inspect(self).get_indicators():
         if isinstance(indicator, Multiplier):
             continue
         detach(indicator, self)
         direction = getattr(indicator, '_time_orientation', abjad.Left)
         if direction == abjad.Left:
             attach(indicator, first_result_leaf)
         elif direction == abjad.Right:
             attach(indicator, last_result_leaf)
         else:
             raise ValueError(direction)
     # move grace containers
     if grace_container is not None:
         container = grace_container[0]
         assert isinstance(container, abjad.GraceContainer), repr(container)
         attach(container, first_result_leaf)
     if after_grace_container is not None:
         container = after_grace_container[0]
         prototype = abjad.AfterGraceContainer
         assert isinstance(container, prototype), repr(container)
         attach(container, last_result_leaf)
     if isinstance(result_components[0], abjad.Tuplet):
         abjad.mutate(result_components).fuse()
     # tie split notes
     if isinstance(self, (abjad.Note, abjad.Chord)) and tie_split_notes:
         result_leaves._attach_tie_spanner_to_leaves(
             repeat_ties=repeat_ties, )
     assert isinstance(result_selections, list), repr(result_selections)
     assert all(isinstance(_, abjad.Selection) for _ in result_selections)
     return result_selections
Пример #11
0
 def _extend_left(self, leaves):
     leaf_input = leaves + list(self[:1])
     leaf_input = select(leaf_input)
     assert leaf_input.are_contiguous_logical_voice()
     for leaf in reversed(leaves):
         self._append_left(leaf)
Пример #12
0
 def _append_left(self, leaf):
     leaves = [leaf] + self[:1]
     leaves = select(leaves)
     assert leaves.are_contiguous_logical_voice()
     leaf._append_spanner(self)
     self._leaves.insert(0, leaf)