Пример #1
0
 def _split_simultaneous_by_duration(
     self,
     duration,
     tie_split_notes=True,
     repeat_ties=False,
     ):
     assert self.is_simultaneous
     left_components, right_components = [], []
     for component in self[:]:
         halves = component._split_by_duration(
             duration=duration,
             tie_split_notes=tie_split_notes,
             repeat_ties=repeat_ties,
             )
         left_components_, right_components_ = halves
         left_components.extend(left_components_)
         right_components.extend(right_components_)
     left_components = select(left_components)
     right_components = select(right_components)
     left_container = self.__copy__()
     right_container = self.__copy__()
     left_container.extend(left_components)
     right_container.extend(right_components)
     if inspect(self).parentage().parent is not None:
         containers = select([left_container, right_container])
         mutate(self).replace(containers)
     # return list-wrapped halves of container
     return [left_container], [right_container]
Пример #2
0
 def _split_simultaneous_by_duration(
     self, duration, tie_split_notes=True, repeat_ties=False
 ):
     assert self.is_simultaneous
     left_components, right_components = [], []
     for component in self[:]:
         halves = component._split_by_duration(
             duration=duration,
             tie_split_notes=tie_split_notes,
             repeat_ties=repeat_ties,
         )
         left_components_, right_components_ = halves
         left_components.extend(left_components_)
         right_components.extend(right_components_)
     left_components = select(left_components)
     right_components = select(right_components)
     left_container = self.__copy__()
     right_container = self.__copy__()
     left_container.extend(left_components)
     right_container.extend(right_components)
     if inspect(self).parentage().parent is not None:
         containers = select([left_container, right_container])
         mutate(self).replace(containers)
     # return list-wrapped halves of container
     return [left_container], [right_container]
Пример #3
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 exceptions.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], 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)
         if not inspect(self).has_spanner(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 inspect(self).has_spanner(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)
Пример #4
0
    def _set_duration(self, new_duration):
        from .Chord import Chord
        from .Note import Note
        from .NoteMaker import NoteMaker
        from .Tuplet import Tuplet
        from abjad.spanners import tie as abjad_tie

        new_duration = Duration(new_duration)
        if self.multiplier is not None:
            multiplier = new_duration.__div__(self.written_duration)
            self.multiplier = multiplier
            return select(self)
        try:
            self.written_duration = new_duration
            return select(self)
        except exceptions.AssignabilityError:
            pass
        maker = NoteMaker()
        components = maker(0, new_duration)
        new_leaves = select(components).leaves()
        following_leaf_count = len(new_leaves) - 1
        following_leaves = following_leaf_count * self
        all_leaves = [self] + following_leaves
        for leaf, new_leaf in zip(all_leaves, new_leaves):
            leaf.written_duration = new_leaf.written_duration
        logical_tie = self._get_logical_tie()
        logical_tie_leaves = list(logical_tie.leaves)
        for leaf in logical_tie:
            detach(Tie, leaf)
            detach(RepeatTie, leaf)
        if self._parent is not None:
            index = self._parent.index(self)
            next_ = index + 1
            self._parent[next_:next_] = following_leaves
        index = logical_tie_leaves.index(self)
        next_ = index + 1
        logical_tie_leaves[next_:next_] = following_leaves
        if 1 < len(logical_tie_leaves) and isinstance(self, (Note, Chord)):
            abjad_tie(logical_tie_leaves)
        if isinstance(components[0], Leaf):
            return select(all_leaves)
        else:
            assert isinstance(components[0], Tuplet)
            assert len(components) == 1
            tuplet = components[0]
            multiplier = tuplet.multiplier
            tuplet = Tuplet(multiplier, [])
            mutate(all_leaves).wrap(tuplet)
            return select(tuplet)
Пример #5
0
    def _set_duration(self, new_duration, repeat_ties=False):
        from .Chord import Chord
        from .Note import Note
        from .NoteMaker import NoteMaker
        from .Tuplet import Tuplet
        from abjad.spanners import tie as abjad_tie

        new_duration = Duration(new_duration)
        if self.multiplier is not None:
            multiplier = new_duration.__div__(self.written_duration)
            self.multiplier = multiplier
            return select(self)
        try:
            self.written_duration = new_duration
            return select(self)
        except exceptions.AssignabilityError:
            pass
        maker = NoteMaker(repeat_ties=repeat_ties)
        components = maker(0, new_duration)
        new_leaves = select(components).leaves()
        following_leaf_count = len(new_leaves) - 1
        following_leaves = following_leaf_count * self
        all_leaves = [self] + following_leaves
        for leaf, new_leaf in zip(all_leaves, new_leaves):
            leaf.written_duration = new_leaf.written_duration
        logical_tie = self._get_logical_tie()
        logical_tie_leaves = list(logical_tie.leaves)
        for leaf in logical_tie:
            detach(TieIndicator, leaf)
            detach(RepeatTie, leaf)
        if self._parent is not None:
            index = self._parent.index(self)
            next_ = index + 1
            self._parent[next_:next_] = following_leaves
        index = logical_tie_leaves.index(self)
        next_ = index + 1
        logical_tie_leaves[next_:next_] = following_leaves
        if 1 < len(logical_tie_leaves) and isinstance(self, (Note, Chord)):
            abjad_tie(logical_tie_leaves)
        if isinstance(components[0], Leaf):
            return select(all_leaves)
        else:
            assert isinstance(components[0], Tuplet)
            assert len(components) == 1
            tuplet = components[0]
            multiplier = tuplet.multiplier
            tuplet = Tuplet(multiplier, [])
            mutate(all_leaves).wrap(tuplet)
            return select(tuplet)
Пример #6
0
 def _initialize_components(self, components):
     if (isinstance(components, collections.Iterable) and
         not isinstance(components, str)):
         components_ = []
         for item in components:
             if isinstance(item, Selection):
                 components_.extend(item)
             elif isinstance(item, str):
                 parsed = self._parse_string(item)
                 components_.append(parsed)
             else:
                 components_.append(item)
         components = components_
         for component in components:
             if not isinstance(component, Component):
                 message = f'must be component: {component!r}.'
                 raise Exception(component)
     if self._all_are_orphan_components(components):
         self._components = list(components)
         self[:]._set_parents(self)
     elif isinstance(components, str):
         parsed = self._parse_string(components)
         self._components = []
         self.is_simultaneous = parsed.is_simultaneous
         if (
             parsed.is_simultaneous or
             not select(parsed[:]).are_contiguous_logical_voice()
             ):
             while len(parsed):
                 self.append(parsed.pop(0))
         else:
             self[:] = parsed[:]
     else:
         raise TypeError(f"can't initialize container from {components!r}.")
Пример #7
0
    def _leaf(self, n):
        from .Container import Container
        from .OnBeatGraceContainer import OnBeatGraceContainer

        assert n in (-1, 0, 1), repr(n)
        if n == 0:
            return self
        sibling = self._sibling(n)
        if sibling is None:
            return None
        if n == 1:
            components = sibling._get_descendants_starting_with()
        else:
            assert n == -1
            if (isinstance(sibling, Container) and len(sibling) == 2 and any(
                    isinstance(_, OnBeatGraceContainer) for _ in sibling)):
                if isinstance(sibling[0], OnBeatGraceContainer):
                    main_voice = sibling[1]
                else:
                    main_voice = sibling[0]
                return main_voice[-1]
            components = sibling._get_descendants_stopping_with()
        for component in components:
            if not isinstance(component, Leaf):
                continue
            if select([self, component]).are_logical_voice():
                return component
Пример #8
0
 def _get_leaves_grouped_by_immediate_parents(self):
     result = []
     pairs_generator = itertools.groupby(self, lambda x: id(x._parent))
     for key, values_generator in pairs_generator:
         group = select(list(values_generator))
         result.append(group)
     return result
Пример #9
0
 def _initialize_components(self, components):
     if isinstance(components, collections.abc.Iterable) and not isinstance(
         components, str
     ):
         components_ = []
         for item in components:
             if isinstance(item, Selection):
                 components_.extend(item)
             elif isinstance(item, str):
                 parsed = self._parse_string(item)
                 components_.append(parsed)
             else:
                 components_.append(item)
         components = components_
         for component in components:
             if not isinstance(component, Component):
                 message = f"must be component: {component!r}."
                 raise Exception(component)
     if self._all_are_orphan_components(components):
         self._components = list(components)
         self[:]._set_parents(self)
     elif isinstance(components, str):
         parsed = self._parse_string(components)
         self._components = []
         self.is_simultaneous = parsed.is_simultaneous
         if (
             parsed.is_simultaneous
             or not select(parsed[:]).are_contiguous_logical_voice()
         ):
             while len(parsed):
                 self.append(parsed.pop(0))
         else:
             self[:] = parsed[:]
     else:
         raise TypeError(f"can't initialize container from {components!r}.")
Пример #10
0
 def _attachment_test_all(self, argument):
     if self._skip_attachment_test_all:
         return True
     result = self._at_least_two_leaves(argument)
     if result is not True:
         return result
     leaves = select(argument).leaves()
     return True
Пример #11
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}.',
         ]
Пример #12
0
 def _extract(self, scale_contents=False):
     if scale_contents:
         self._scale_contents(self.multiplier)
     selection = select([self])
     parent, start, stop = selection._get_parent_and_start_stop_indices()
     components = list(getattr(self, "components", ()))
     parent.__setitem__(slice(start, stop + 1), components)
     return self
Пример #13
0
 def _extract(self, scale_contents=False):
     if scale_contents:
         self._scale_contents(self.multiplier)
     selection = select([self])
     parent, start, stop = selection._get_parent_and_start_stop_indices()
     components = list(getattr(self, 'components', ()))
     parent.__setitem__(slice(start, stop + 1), components)
     return self
Пример #14
0
 def __getitem__(self, argument) -> typing.Union[Leaf, Selection]:
     """
     Gets leaf or selection identified by ``argument``.
     """
     if isinstance(argument, slice):
         leaves = self.leaves.__getitem__(argument)
         return select(leaves)
     return self.leaves.__getitem__(argument)
Пример #15
0
 def _set_leaf_durations(self):
     if self.leaf_duration is None:
         return
     for leaf in select(self).leaves():
         duration = abjad_inspect(leaf).duration()
         if duration != self.leaf_duration:
             multiplier = self.leaf_duration / duration
             leaf.multiplier = multiplier
Пример #16
0
 def leaves(self) -> Selection:
     """
     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)
Пример #17
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, Leaf)]
     for candidate in candidates:
         selection = select([component, candidate])
         if selection.are_logical_voice():
             return candidate
Пример #18
0
    def __getitem__(self, argument) -> typing.Union[Component, Selection]:
        """
        Gets item or slice identified by ``argument``.

        Traverses top-level items only.
        """
        if isinstance(argument, int):
            return self.components.__getitem__(argument)
        elif isinstance(argument, slice) and not self.is_simultaneous:
            return select(self.components.__getitem__(argument))
        elif isinstance(argument, slice) and self.is_simultaneous:
            return select(self.components.__getitem__(argument))
        elif isinstance(argument, str):
            if argument not in self._named_children:
                raise ValueError(f"can not find component named {argument!r}.")
            elif 1 < len(self._named_children.__getitem__(argument)):
                raise ValueError(f"multiple components named {argument!r}.")
            return self._named_children.__getitem__(argument)[0]
        raise ValueError(f"can not get container at {argument!r}.")
Пример #19
0
    def __getitem__(self, argument) -> typing.Union[Component, Selection]:
        """
        Gets item or slice identified by ``argument``.

        Traverses top-level items only.
        """
        if isinstance(argument, int):
            return self.components.__getitem__(argument)
        elif isinstance(argument, slice) and not self.is_simultaneous:
            return select(self.components.__getitem__(argument))
        elif isinstance(argument, slice) and self.is_simultaneous:
            return select(self.components.__getitem__(argument))
        elif isinstance(argument, str):
            if argument not in self._named_children:
                raise ValueError(f'can not find component named {argument!r}.')
            elif 1 < len(self._named_children.__getitem__(argument)):
                raise ValueError(f'multiple components named {argument!r}.')
            return self._named_children.__getitem__(argument)[0]
        raise ValueError(f'can not get container at {argument!r}.')
Пример #20
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)
Пример #21
0
    def __mul__(self, n):
        """
        Copies component `n` times and detaches spanners.

        Returns list of new components.
        """
        components = []
        for i in range(n):
            component = mutate(self).copy()
            components.append(component)
        result = select(components)
        return result
Пример #22
0
    def __mul__(self, n):
        """
        Copies component `n` times and detaches spanners.

        Returns list of new components.
        """
        components = []
        for i in range(n):
            component = mutate(self).copy()
            components.append(component)
        result = select(components)
        return result
Пример #23
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
Пример #24
0
 def _append(self, leaf):
     if self._ignore_attachment_test:
         pass
     elif not self._attachment_test(leaf):
         raise Exception(f'can not attach {self!r} to {leaf!r}.')
     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)
Пример #25
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
Пример #26
0
 def _get_on_beat_anchor_leaf(self):
     container = self._parent
     if container is None:
         return None
     if len(container) != 2:
         message = "Combine on-beat grace container with one other voice."
         raise Exception(message)
     if container.index(self) == 0:
         anchor_voice = container[-1]
     else:
         assert container.index(self) == 1
         anchor_voice = container[0]
     anchor_leaf = select(anchor_voice).leaf(0, grace=False)
     return anchor_leaf
Пример #27
0
 def _leaf(self, n):
     assert n in (-1, 0, 1), repr(n)
     if n == 0:
         return self
     sibling = self._sibling(n)
     if sibling is None:
         return None
     if n == 1:
         components = sibling._get_descendants_starting_with()
     else:
         components = sibling._get_descendants_stopping_with()
     for component in components:
         if not isinstance(component, Leaf):
             continue
         if select([self, component]).are_logical_voice():
             return component
Пример #28
0
 def _leaf(self, n):
     assert n in (-1, 0, 1), repr(n)
     if n == 0:
         return self
     sibling = self._sibling(n)
     if sibling is None:
         return None
     if n == 1:
         components = sibling._get_descendants_starting_with()
     else:
         components = sibling._get_descendants_stopping_with()
     for component in components:
         if not isinstance(component, Leaf):
             continue
         if select([self, component]).are_logical_voice():
             return component
Пример #29
0
    def _split_at_index(self, i):
        """
        Splits container to the left of index ``i``.

        Preserves tuplet multiplier when container is a tuplet.

        Preserves time signature denominator when container is a measure.

        Resizes resizable containers.

        Returns split parts.
        """
        from .Tuplet import Tuplet

        # partition my components
        left_components = self[:i]
        right_components = self[i:]
        # instantiate new left and right containers
        if isinstance(self, Tuplet):
            multiplier = self.multiplier
            left = type(self)(multiplier, [])
            mutate(left_components).wrap(left)
            right = type(self)(multiplier, [])
            mutate(right_components).wrap(right)
        else:
            left = self.__copy__()
            mutate(left_components).wrap(left)
            right = self.__copy__()
            mutate(right_components).wrap(right)
        # save left and right containers together for iteration
        halves = (left, right)
        nonempty_halves = [half for half in halves if len(half)]
        # incorporate left and right parents in score if possible
        selection = select(self)
        parent, start, stop = selection._get_parent_and_start_stop_indices()
        if parent is not None:
            parent._components.__setitem__(
                slice(start, stop + 1), nonempty_halves
            )
            for part in nonempty_halves:
                part._set_parent(parent)
        else:
            left._set_parent(None)
            right._set_parent(None)
        # return new left and right containers
        return halves
Пример #30
0
    def _split_at_index(self, i):
        """
        Splits container to the left of index ``i``.

        Preserves tuplet multiplier when container is a tuplet.

        Preserves time signature denominator when container is a measure.

        Resizes resizable containers.

        Returns split parts.
        """
        from .Tuplet import Tuplet

        # partition my components
        left_components = self[:i]
        right_components = self[i:]
        # instantiate new left and right containers
        if isinstance(self, Tuplet):
            multiplier = self.multiplier
            left = type(self)(multiplier, [])
            mutate(left_components).wrap(left)
            right = type(self)(multiplier, [])
            mutate(right_components).wrap(right)
        else:
            left = self.__copy__()
            mutate(left_components).wrap(left)
            right = self.__copy__()
            mutate(right_components).wrap(right)
        # save left and right containers together for iteration
        halves = (left, right)
        nonempty_halves = [half for half in halves if len(half)]
        # incorporate left and right parents in score if possible
        selection = select(self)
        parent, start, stop = selection._get_parent_and_start_stop_indices()
        if parent is not None:
            parent._components.__setitem__(slice(start, stop + 1),
                                           nonempty_halves)
            for part in nonempty_halves:
                part._set_parent(parent)
        else:
            left._set_parent(None)
            right._set_parent(None)
        # return new left and right containers
        return halves
Пример #31
0
 def __init__(self, component=None, cross_offset=None):
     assert isinstance(component, (Component, type(None)))
     self._component = component
     if component is None:
         components = ()
     else:
         components = list(select(component).components())
     result = []
     if cross_offset is None:
         result = components
     else:
         for component in components:
             append_x = True
             if not (inspect(component).timespan().start_offset <
                     cross_offset and cross_offset <
                     inspect(component).timespan().stop_offset):
                 append_x = False
             if append_x:
                 result.append(component)
     self._components = tuple(result)
Пример #32
0
 def _split_by_duration(
     self,
     duration,
     tie_split_notes=True,
     repeat_ties=False,
     ):
     if self.is_simultaneous:
         return self._split_simultaneous_by_duration(
             duration=duration,
             tie_split_notes=tie_split_notes,
             repeat_ties=repeat_ties,
             )
     duration = Duration(duration)
     assert 0 <= duration, repr(duration)
     if duration == 0:
         return [], self
     # get split point score offset
     timespan = inspect(self).timespan()
     global_split_point = timespan.start_offset + duration
     # get any duration-crossing descendents
     cross_offset = timespan.start_offset + duration
     duration_crossing_descendants = []
     for descendant in inspect(self).descendants():
         timespan = inspect(descendant).timespan()
         start_offset = timespan.start_offset
         stop_offset = timespan.stop_offset
         if start_offset < cross_offset < stop_offset:
             duration_crossing_descendants.append(descendant)
     # any duration-crossing leaf will be at end of list
     bottom = duration_crossing_descendants[-1]
     did_split_leaf = False
     # if split point necessitates leaf split
     if isinstance(bottom, Leaf):
         assert isinstance(bottom, Leaf)
         did_split_leaf = True
         timespan = inspect(bottom).timespan()
         start_offset = timespan.start_offset
         split_point_in_bottom = global_split_point - start_offset
         new_leaves = bottom._split_by_durations(
             [split_point_in_bottom],
             tie_split_notes=tie_split_notes,
             repeat_ties=repeat_ties,
             )
         for leaf in new_leaves:
             timespan = inspect(leaf).timespan()
             if timespan.stop_offset == global_split_point:
                 leaf_left_of_split = leaf
             if timespan.start_offset == global_split_point:
                 leaf_right_of_split = leaf
         duration_crossing_containers = duration_crossing_descendants[:-1]
         if not len(duration_crossing_containers):
             return left_list, right_list
     # if split point falls between leaves
     # then find leaf to immediate right of split point
     # in order to start upward crawl through duration-crossing containers
     else:
         duration_crossing_containers = duration_crossing_descendants[:]
         for leaf in iterate(bottom).leaves():
             timespan = inspect(leaf).timespan()
             if timespan.start_offset == global_split_point:
                 leaf_right_of_split = leaf
                 leaf_left_of_split = inspect(leaf).leaf(-1)
                 break
         else:
             raise Exception('can not split empty container {bottom!r}.')
     assert leaf_left_of_split is not None
     assert leaf_right_of_split is not None
     # find component to right of split
     # that is also immediate child of last duration-crossing container
     for component in inspect(leaf_right_of_split).parentage():
         parent = inspect(component).parentage().parent
         if parent is duration_crossing_containers[-1]:
             highest_level_component_right_of_split = component
             break
     else:
         raise ValueError('should not be able to get here.')
     # crawl back up through duration-crossing containers and split each
     previous = highest_level_component_right_of_split
     for container in reversed(duration_crossing_containers):
         assert isinstance(container, Container)
         index = container.index(previous)
         left, right = container._split_at_index(index)
         previous = right
     # reapply tie here if crawl above killed tie applied to leaves
     if did_split_leaf:
         if (
             tie_split_notes and
             isinstance(leaf_left_of_split, Note)
             ):
             if (
                 inspect(leaf_left_of_split).parentage().root is
                 inspect(leaf_right_of_split).parentage().root
                 ):
                 leaves_around_split = (
                     leaf_left_of_split,
                     leaf_right_of_split,
                     )
                 selection = select(leaves_around_split)
                 selection._attach_tie_to_leaves(repeat_ties=repeat_ties)
     # return list-wrapped halves of container
     return [left], [right]
Пример #33
0
 def _get_contents(self):
     result = []
     result.append(self)
     result.extend(getattr(self, "components", []))
     result = select(result)
     return result
Пример #34
0
    def __delitem__(self, i):
        r"""
        Deletes components(s) at index ``i`` in container.

        ..  container:: example

            Deletes first tuplet in voice:

            >>> voice = abjad.Voice()
            >>> voice.append(abjad.Tuplet((2, 3), "c'4 d'4 e'4"))
            >>> voice.append(abjad.Tuplet((2, 3), "e'4 d'4 c'4"))
            >>> leaves = abjad.select(voice).leaves()
            >>> abjad.slur(leaves)
            >>> abjad.show(voice) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(voice)
                \new Voice
                {
                    \times 2/3 {
                        c'4
                        (
                        d'4
                        e'4
                    }
                    \times 2/3 {
                        e'4
                        d'4
                        c'4
                        )
                    }
                }

            >>> tuplet_1 = voice[0]
            >>> del(voice[0])
            >>> start_slur = abjad.StartSlur()
            >>> leaf = abjad.select(voice).leaf(0)
            >>> abjad.attach(start_slur, leaf)

            First tuplet no longer appears in voice:

                >>> abjad.show(voice) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(voice)
                \new Voice
                {
                    \times 2/3 {
                        e'4
                        (
                        d'4
                        c'4
                        )
                    }
                }

            >>> abjad.inspect(voice).wellformed()
            True

            First tuplet must have start slur removed:

            >>> abjad.detach(abjad.StartSlur, tuplet_1[0])
            (StartSlur(),)

            >>> abjad.show(tuplet_1) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(tuplet_1)
                \times 2/3 {
                    c'4
                    d'4
                    e'4
                }

            >>> abjad.inspect(tuplet_1).wellformed()
            True

        Returns none.
        """
        components = self[i]
        if not isinstance(components, Selection):
            components = select([components])
        components._set_parents(None)
Пример #35
0
def hairpin(
    descriptor: str,
    argument: typing.Union[Component, Selection],
    *,
    selector: typings.Selector = 'abjad.select().leaves()',
) -> None:
    r"""
    Attaches hairpin indicators.

    ..  container:: example

        With three-part string descriptor:

        >>> staff = abjad.Staff("c'4 d' e' f'")
        >>> abjad.hairpin('p < f', staff[:])
        >>> abjad.override(staff[0]).dynamic_line_spanner.staff_padding = 4
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \once \override DynamicLineSpanner.staff-padding = #4
                c'4
                \p
                \<
                d'4
                e'4
                f'4
                \f
            }

    ..  container:: example

        With dynamic objects:

        >>> staff = abjad.Staff("c'4 d' e' f'")
        >>> start = abjad.Dynamic('niente', command=r'\!')
        >>> trend = abjad.DynamicTrend('o<|')
        >>> abjad.tweak(trend).color = 'blue'
        >>> stop = abjad.Dynamic('"f"')
        >>> abjad.hairpin([start, trend, stop], staff[:])
        >>> abjad.override(staff[0]).dynamic_line_spanner.staff_padding = 4
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \once \override DynamicLineSpanner.staff-padding = #4
                c'4
                \!
                - \tweak color #blue
                - \tweak circled-tip ##t
                - \tweak stencil #abjad-flared-hairpin
                \<
                d'4
                e'4
                f'4
                _ #(make-dynamic-script
                    (markup
                        #:whiteout
                        #:line (
                            #:general-align Y -2 #:normal-text #:larger "“"
                            #:hspace -0.4
                            #:dynamic "f"
                            #:hspace -0.2
                            #:general-align Y -2 #:normal-text #:larger "”"
                            )
                        )
                    )
            }

    """
    import abjad

    indicators: typing.List = []
    start_dynamic: typing.Optional[Dynamic]
    dynamic_trend: typing.Optional[DynamicTrend]
    stop_dynamic: typing.Optional[Dynamic]
    known_shapes = DynamicTrend('<').known_shapes
    if isinstance(descriptor, str):
        for string in descriptor.split():
            if string in known_shapes:
                dynamic_trend = DynamicTrend(string)
                indicators.append(dynamic_trend)
            else:
                dynamic = Dynamic(string)
                indicators.append(dynamic)
    else:
        assert isinstance(descriptor, list), repr(descriptor)
        indicators = descriptor

    start_dynamic, dynamic_trend, stop_dynamic = None, None, None
    if len(indicators) == 1:
        if isinstance(indicators[0], Dynamic):
            start_dynamic = indicators[0]
        else:
            dynamic_trend = indicators[0]
    elif len(indicators) == 2:
        if isinstance(indicators[0], Dynamic):
            start_dynamic = indicators[0]
            dynamic_trend = indicators[1]
        else:
            dynamic_trend = indicators[0]
            stop_dynamic = indicators[1]
    elif len(indicators) == 3:
        start_dynamic, dynamic_trend, stop_dynamic = indicators
    else:
        raise Exception(indicators)

    assert isinstance(start_dynamic, Dynamic), repr(start_dynamic)

    if isinstance(selector, str):
        selector = eval(selector)
    assert isinstance(selector, Expression)
    argument = selector(argument)
    leaves = select(argument).leaves()
    start_leaf = leaves[0]
    stop_leaf = leaves[-1]

    if start_dynamic is not None:
        attach(start_dynamic, start_leaf)
    if dynamic_trend is not None:
        attach(dynamic_trend, start_leaf)
    if stop_dynamic is not None:
        attach(stop_dynamic, stop_leaf)
Пример #36
0
    def attach_defaults(self, argument) -> typing.List:
        """
        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 = const.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 leaf 0 in first nonempty voice
            for voice in voices:
                leaves = []
                for leaf_ in select(voice).leaves():
                    if inspect(leaf_).annotation(const.HIDDEN) is not True:
                        leaves.append(leaf_)
                if not all(isinstance(_, empty_prototype) for _ in leaves):
                    leaf = inspect(voice).leaf(0)
                    break
            # 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).parentage():
                        if inspect(component).annotation(tag) is True:
                            voice_might_vanish = True
                    if not voice_might_vanish:
                        leaf = inspect(voice).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]).leaf(0)
            if leaf is None:
                continue
            instrument = inspect(leaf).indicator(instruments.Instrument)
            if instrument is None:
                string = "default_instrument"
                instrument = inspect(staff__group).annotation(string)
                if instrument is not None:
                    wrapper = attach(
                        instrument,
                        leaf,
                        context=staff__group.lilypond_type,
                        tag="abjad.ScoreTemplate.attach_defaults",
                        wrapper=True,
                    )
                    wrappers.append(wrapper)
            margin_markup = inspect(leaf).indicator(MarginMarkup)
            if margin_markup is None:
                string = "default_margin_markup"
                margin_markup = inspect(staff__group).annotation(string)
                if margin_markup is not None:
                    wrapper = attach(
                        margin_markup,
                        leaf,
                        tag=Tag("-PARTS").prepend(
                            "abjad.ScoreTemplate.attach_defaults"
                        ),
                        wrapper=True,
                    )
                    wrappers.append(wrapper)
        for staff in staves:
            leaf = inspect(staff).leaf(0)
            clef = inspect(leaf).indicator(Clef)
            if clef is not None:
                continue
            clef = inspect(staff).annotation("default_clef")
            if clef is not None:
                wrapper = attach(
                    clef,
                    leaf,
                    tag="abjad.ScoreTemplate.attach_defaults",
                    wrapper=True,
                )
                wrappers.append(wrapper)
        return wrappers
Пример #37
0
 def _split_by_duration(
     self, duration, tie_split_notes=True, repeat_ties=False
 ):
     if self.is_simultaneous:
         return self._split_simultaneous_by_duration(
             duration=duration,
             tie_split_notes=tie_split_notes,
             repeat_ties=repeat_ties,
         )
     duration = Duration(duration)
     assert 0 <= duration, repr(duration)
     if duration == 0:
         return [], self
     # get split point score offset
     timespan = inspect(self).timespan()
     global_split_point = timespan.start_offset + duration
     # get any duration-crossing descendents
     cross_offset = timespan.start_offset + duration
     duration_crossing_descendants = []
     for descendant in inspect(self).descendants():
         timespan = inspect(descendant).timespan()
         start_offset = timespan.start_offset
         stop_offset = timespan.stop_offset
         if start_offset < cross_offset < stop_offset:
             duration_crossing_descendants.append(descendant)
     # any duration-crossing leaf will be at end of list
     bottom = duration_crossing_descendants[-1]
     did_split_leaf = False
     # if split point necessitates leaf split
     if isinstance(bottom, Leaf):
         assert isinstance(bottom, Leaf)
         did_split_leaf = True
         timespan = inspect(bottom).timespan()
         start_offset = timespan.start_offset
         split_point_in_bottom = global_split_point - start_offset
         new_leaves = bottom._split_by_durations(
             [split_point_in_bottom],
             tie_split_notes=tie_split_notes,
             repeat_ties=repeat_ties,
         )
         for leaf in new_leaves:
             timespan = inspect(leaf).timespan()
             if timespan.stop_offset == global_split_point:
                 leaf_left_of_split = leaf
             if timespan.start_offset == global_split_point:
                 leaf_right_of_split = leaf
         duration_crossing_containers = duration_crossing_descendants[:-1]
         if not len(duration_crossing_containers):
             return left_list, right_list
     # if split point falls between leaves
     # then find leaf to immediate right of split point
     # in order to start upward crawl through duration-crossing containers
     else:
         duration_crossing_containers = duration_crossing_descendants[:]
         for leaf in iterate(bottom).leaves():
             timespan = inspect(leaf).timespan()
             if timespan.start_offset == global_split_point:
                 leaf_right_of_split = leaf
                 leaf_left_of_split = inspect(leaf).leaf(-1)
                 break
         else:
             raise Exception("can not split empty container {bottom!r}.")
     assert leaf_left_of_split is not None
     assert leaf_right_of_split is not None
     # find component to right of split
     # that is also immediate child of last duration-crossing container
     for component in inspect(leaf_right_of_split).parentage():
         parent = inspect(component).parentage().parent
         if parent is duration_crossing_containers[-1]:
             highest_level_component_right_of_split = component
             break
     else:
         raise ValueError("should not be able to get here.")
     # crawl back up through duration-crossing containers and split each
     previous = highest_level_component_right_of_split
     for container in reversed(duration_crossing_containers):
         assert isinstance(container, Container)
         index = container.index(previous)
         left, right = container._split_at_index(index)
         previous = right
     # reapply tie here if crawl above killed tie applied to leaves
     if did_split_leaf:
         if tie_split_notes and isinstance(leaf_left_of_split, Note):
             if (
                 inspect(leaf_left_of_split).parentage().root
                 is inspect(leaf_right_of_split).parentage().root
             ):
                 leaves_around_split = (
                     leaf_left_of_split,
                     leaf_right_of_split,
                 )
                 selection = select(leaves_around_split)
                 selection._attach_tie_to_leaves(repeat_ties=repeat_ties)
     # return list-wrapped halves of container
     return [left], [right]
Пример #38
0
    def _split_by_durations(
        self,
        durations,
        cyclic=False,
        tie_split_notes=True,
        repeat_ties=False,
        ):
        from .AfterGraceContainer import AfterGraceContainer
        from .Chord import Chord
        from .GraceContainer import GraceContainer
        from .Note import Note
        from .Selection import Selection
        from .Tuplet import Tuplet
        durations = [Duration(_) for _ in durations]
        durations = Sequence(durations)
        leaf_duration = inspect(self).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 = Sequence(durations)
        durations = durations.truncate(weight=leaf_duration)
        originally_tied = inspect(self).has_indicator(TieIndicator)
        originally_repeat_tied = inspect(self).has_indicator(RepeatTie)
        result_selections = []
        grace_container = self._detach_grace_container()
        after_grace_container = self._detach_after_grace_container()
        leaf_prolation = inspect(self).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 = Sequence(result_selections).flatten(depth=-1)
        result_components = select(result_components)
        result_leaves = select(result_components).leaves(grace_notes=False)
        assert all(isinstance(_, Selection) for _ in result_selections)
        assert all(isinstance(_, Component) for _ in result_components)
        assert result_leaves.are_leaves()
#        for leaf in result_leaves:
#            detach(Tie, leaf)
        # strip result leaves of all indicators
        for leaf in result_leaves:
            detach(object, leaf)
        # replace leaf with flattened result
        if self._parent is not None:
            mutate(self).replace(result_components)
        # move indicators
        first_result_leaf = result_leaves[0]
        last_result_leaf = result_leaves[-1]
        for indicator in inspect(self).indicators():
            detach(indicator, self)
            direction = getattr(indicator, '_time_orientation', enums.Left)
            if direction is enums.Left:
                attach(indicator, first_result_leaf)
            elif direction == enums.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, GraceContainer), repr(container)
            attach(container, first_result_leaf)
        if after_grace_container is not None:
            container = after_grace_container[0]
            prototype = AfterGraceContainer
            assert isinstance(container, prototype), repr(container)
            attach(container, last_result_leaf)
        if isinstance(result_components[0], Tuplet):
            mutate(result_components).fuse()
        # tie split notes
        if (tie_split_notes and
            isinstance(self, (Note, Chord)) and
            1 < len(result_leaves)):
            result_leaves._attach_tie_to_leaves(repeat_ties=repeat_ties)
        #assert not inspect(result_leaves[0]).has_indicator(RepeatTie)
        detach(RepeatTie, result_leaves[0])
        #assert not inspect(result_leaves[-1]).has_indicator(TieIndicator)
        detach(TieIndicator, result_leaves[-1])
        if originally_repeat_tied:
            tie = RepeatTie()
            attach(tie, result_leaves[0])
        if originally_tied:
            tie = TieIndicator()
            attach(tie, result_leaves[-1])
        assert isinstance(result_leaves, Selection)
        assert all(isinstance(_, Leaf) for _ in result_leaves)
        return result_leaves
Пример #39
0
    def __delitem__(self, i):
        r"""
        Deletes components(s) at index ``i`` in container.

        ..  container:: example

            Deletes first tuplet in voice:

            >>> voice = abjad.Voice()
            >>> voice.append(abjad.Tuplet((2, 3), "c'4 d'4 e'4"))
            >>> voice.append(abjad.Tuplet((2, 3), "e'4 d'4 c'4"))
            >>> leaves = abjad.select(voice).leaves()
            >>> abjad.slur(leaves)
            >>> abjad.show(voice) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(voice)
                \new Voice
                {
                    \times 2/3 {
                        c'4
                        (
                        d'4
                        e'4
                    }
                    \times 2/3 {
                        e'4
                        d'4
                        c'4
                        )
                    }
                }

            >>> tuplet_1 = voice[0]
            >>> del(voice[0])
            >>> start_slur = abjad.StartSlur()
            >>> leaf = abjad.select(voice).leaf(0)
            >>> abjad.attach(start_slur, leaf)

            First tuplet no longer appears in voice:

                >>> abjad.show(voice) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(voice)
                \new Voice
                {
                    \times 2/3 {
                        e'4
                        (
                        d'4
                        c'4
                        )
                    }
                }

            >>> abjad.inspect(voice).wellformed()
            True

            First tuplet must have start slur removed:

            >>> abjad.detach(abjad.StartSlur, tuplet_1[0])
            (StartSlur(),)

            >>> abjad.show(tuplet_1) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(tuplet_1)
                \times 2/3 {
                    c'4
                    d'4
                    e'4
                }

            >>> abjad.inspect(tuplet_1).wellformed()
            True

        Returns none.
        """
        components = self[i]
        if not isinstance(components, Selection):
            components = select([components])
        components._set_parents(None)
Пример #40
0
 def _get_contents(self):
     result = []
     result.append(self)
     result.extend(getattr(self, "components", []))
     result = select(result)
     return result
Пример #41
0
    def _split_by_durations(
        self, durations, cyclic=False, tie_split_notes=True, repeat_ties=False
    ):
        from .AfterGraceContainer import AfterGraceContainer
        from .Chord import Chord
        from .GraceContainer import GraceContainer
        from .Note import Note
        from .Selection import Selection
        from .Tuplet import Tuplet

        durations = [Duration(_) for _ in durations]
        durations = Sequence(durations)
        leaf_duration = inspect(self).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 = Sequence(durations)
        durations = durations.truncate(weight=leaf_duration)
        originally_tied = inspect(self).has_indicator(TieIndicator)
        originally_repeat_tied = inspect(self).has_indicator(RepeatTie)
        result_selections = []
        grace_container = self._detach_grace_container()
        after_grace_container = self._detach_after_grace_container()
        leaf_prolation = inspect(self).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 = Sequence(result_selections).flatten(depth=-1)
        result_components = select(result_components)
        result_leaves = select(result_components).leaves(grace_notes=False)
        assert all(isinstance(_, Selection) for _ in result_selections)
        assert all(isinstance(_, Component) for _ in result_components)
        assert result_leaves.are_leaves()
        #        for leaf in result_leaves:
        #            detach(Tie, leaf)
        # strip result leaves of all indicators
        for leaf in result_leaves:
            detach(object, leaf)
        # replace leaf with flattened result
        if self._parent is not None:
            mutate(self).replace(result_components)
        # move indicators
        first_result_leaf = result_leaves[0]
        last_result_leaf = result_leaves[-1]
        for indicator in inspect(self).indicators():
            detach(indicator, self)
            direction = getattr(indicator, "_time_orientation", enums.Left)
            if direction is enums.Left:
                attach(indicator, first_result_leaf)
            elif direction == enums.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, GraceContainer), repr(container)
            attach(container, first_result_leaf)
        if after_grace_container is not None:
            container = after_grace_container[0]
            prototype = AfterGraceContainer
            assert isinstance(container, prototype), repr(container)
            attach(container, last_result_leaf)
        if isinstance(result_components[0], Tuplet):
            mutate(result_components).fuse()
        # tie split notes
        if (
            tie_split_notes
            and isinstance(self, (Note, Chord))
            and 1 < len(result_leaves)
        ):
            result_leaves._attach_tie_to_leaves(repeat_ties=repeat_ties)
        # assert not inspect(result_leaves[0]).has_indicator(RepeatTie)
        detach(RepeatTie, result_leaves[0])
        # assert not inspect(result_leaves[-1]).has_indicator(TieIndicator)
        detach(TieIndicator, result_leaves[-1])
        if originally_repeat_tied:
            tie = RepeatTie()
            attach(tie, result_leaves[0])
        if originally_tied:
            tie = TieIndicator()
            attach(tie, result_leaves[-1])
        assert isinstance(result_leaves, Selection)
        assert all(isinstance(_, Leaf) for _ in result_leaves)
        return result_leaves
Пример #42
0
    def attach_defaults(self, argument) -> typing.List:
        """
        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 = const.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 leaf 0 in first nonempty voice
            for voice in voices:
                leaves = []
                for leaf_ in select(voice).leaves():
                    if inspect(leaf_).has_indicator(const.HIDDEN):
                        leaves.append(leaf_)
                if not all(isinstance(_, empty_prototype) for _ in leaves):
                    leaf = inspect(voice).leaf(0)
                    break
            # 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).parentage():
                        if inspect(component).annotation(tag) is True:
                            voice_might_vanish = True
                    if not voice_might_vanish:
                        leaf = inspect(voice).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]).leaf(0)
            if leaf is None:
                continue
            instrument = inspect(leaf).indicator(instruments.Instrument)
            if instrument is None:
                string = "default_instrument"
                instrument = inspect(staff__group).annotation(string)
                if instrument is not None:
                    wrapper = attach(
                        instrument,
                        leaf,
                        context=staff__group.lilypond_type,
                        tag=Tag("abjad.ScoreTemplate.attach_defaults(1)"),
                        wrapper=True,
                    )
                    wrappers.append(wrapper)
            margin_markup = inspect(leaf).indicator(MarginMarkup)
            if margin_markup is None:
                string = "default_margin_markup"
                margin_markup = inspect(staff__group).annotation(string)
                if margin_markup is not None:
                    wrapper = attach(
                        margin_markup,
                        leaf,
                        tag=abjad_tags.NOT_PARTS.append(
                            Tag("abjad.ScoreTemplate.attach_defaults(2)")),
                        wrapper=True,
                    )
                    wrappers.append(wrapper)
        for staff in staves:
            leaf = inspect(staff).leaf(0)
            clef = inspect(leaf).indicator(Clef)
            if clef is not None:
                continue
            clef = inspect(staff).annotation("default_clef")
            if clef is not None:
                wrapper = attach(
                    clef,
                    leaf,
                    tag=Tag("abjad.ScoreTemplate.attach_defaults(3)"),
                    wrapper=True,
                )
                wrappers.append(wrapper)
        return wrappers
Пример #43
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 = sequence(durations)
     leaf_duration = inspect(self).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 = 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 = inspect(self).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 = 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 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 = inspect(leaf).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 inspect(first_selection[-1]).spanners():
             index = spanner._index(first_selection[-1])
             spanner._fracture(index, direction=enums.Right)
         last_selection = result_selections[-1]
         for spanner in inspect(last_selection[0]).spanners():
             index = spanner._index(last_selection[0])
             spanner._fracture(index, direction=enums.Left)
         for middle_selection in result_selections[1:-1]:
             spanners = inspect(middle_selection[0]).spanners()
             for spanner in spanners:
                 index = spanner._index(middle_selection[0])
                 spanner._fracture(index, direction=enums.Left)
             spanners = inspect(middle_selection[-1]).spanners()
             for spanner in spanners:
                 index = spanner._index(middle_selection[-1])
                 spanner._fracture(index, direction=enums.Right)
     # move indicators
     first_result_leaf = result_leaves[0]
     last_result_leaf = result_leaves[-1]
     for indicator in inspect(self).indicators():
         if isinstance(indicator, Multiplier):
             continue
         detach(indicator, self)
         direction = getattr(indicator, '_time_orientation', enums.Left)
         if direction is enums.Left:
             attach(indicator, first_result_leaf)
         elif direction == enums.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_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
Пример #44
0
 def _attachment_test_all(self, argument):
     if isinstance(argument, (Chord, Note)):
         return True
     assert all(isinstance(_, Leaf) for _ in argument)
     leaves = select(argument).leaves()
     return 1 <= len(leaves)