Exemplo n.º 1
0
    def __copy__(self, *arguments):
        """
        Shallow copies component.

        Copies indicators.

        Does not copy spanners.

        Does not copy children.

        Returns new component.
        """
        new_component = type(self)(*self.__getnewargs__())
        if getattr(self, "_overrides", None) is not None:
            manager = copy.copy(override(self))
            new_component._overrides = manager
        if getattr(self, "_lilypond_setting_name_manager", None) is not None:
            manager = copy.copy(setting(self))
            new_component._lilypond_setting_name_manager = manager
        for wrapper in inspect(self).annotation_wrappers():
            new_wrapper = copy.copy(wrapper)
            attach(new_wrapper, new_component)
        for wrapper in inspect(self).wrappers():
            new_wrapper = copy.copy(wrapper)
            attach(new_wrapper, new_component)
        return new_component
Exemplo n.º 2
0
 def _process_post_events(self, leaf, post_events):
     nonspanner_post_event_types = (
         abjad_indicators.Articulation,
         abjad_indicators.BarLine,
         abjad_indicators.Dynamic,
         abjad_indicators.GlissandoIndicator,
         abjad_indicators.StartHairpin,
         abjad_indicators.LilyPondLiteral,
         abjad_indicators.StartBeam,
         abjad_indicators.StartGroup,
         abjad_indicators.StartPhrasingSlur,
         abjad_indicators.StartSlur,
         abjad_indicators.StartTextSpan,
         abjad_indicators.StartTrillSpan,
         abjad_indicators.StopBeam,
         abjad_indicators.StopGroup,
         abjad_indicators.StopHairpin,
         abjad_indicators.StopSlur,
         abjad_indicators.StopPhrasingSlur,
         abjad_indicators.StopTextSpan,
         abjad_indicators.StopTrillSpan,
         abjad_indicators.StemTremolo,
         abjad_indicators.TieIndicator,
         abjad_markups.Markup,
     )
     for post_event in post_events:
         if isinstance(post_event, nonspanner_post_event_types):
             attach(post_event, leaf)
Exemplo n.º 3
0
    def __copy__(self, *arguments):
        """
        Shallow copies component.

        Copies indicators.

        Does not copy spanners.

        Does not copy children.

        Returns new component.
        """
        new_component = type(self)(*self.__getnewargs__())
        if getattr(self, "_overrides", None) is not None:
            manager = copy.copy(override(self))
            new_component._overrides = manager
        if getattr(self, "_lilypond_setting_name_manager", None) is not None:
            manager = copy.copy(setting(self))
            new_component._lilypond_setting_name_manager = manager
        for wrapper in inspect(self).annotation_wrappers():
            new_wrapper = copy.copy(wrapper)
            attach(new_wrapper, new_component)
        for wrapper in inspect(self).wrappers():
            new_wrapper = copy.copy(wrapper)
            attach(new_wrapper, new_component)
        return new_component
Exemplo n.º 4
0
 def _process_post_events(self, leaf, post_events):
     nonspanner_post_event_types = (
         abjad_indicators.Articulation,
         abjad_indicators.BarLine,
         abjad_indicators.Dynamic,
         abjad_indicators.GlissandoIndicator,
         abjad_indicators.StartHairpin,
         abjad_indicators.LilyPondLiteral,
         abjad_indicators.StartBeam,
         abjad_indicators.StartGroup,
         abjad_indicators.StartPhrasingSlur,
         abjad_indicators.StartSlur,
         abjad_indicators.StartTextSpan,
         abjad_indicators.StartTrillSpan,
         abjad_indicators.StopBeam,
         abjad_indicators.StopGroup,
         abjad_indicators.StopHairpin,
         abjad_indicators.StopSlur,
         abjad_indicators.StopPhrasingSlur,
         abjad_indicators.StopTextSpan,
         abjad_indicators.StopTrillSpan,
         abjad_indicators.StemTremolo,
         abjad_indicators.Tie,
         abjad_markups.Markup,
     )
     for post_event in post_events:
         if isinstance(post_event, nonspanner_post_event_types):
             attach(post_event, leaf)
Exemplo n.º 5
0
 def _construct_context_specced_music(self, context, optional_id,
                                      optional_context_mod, music):
     known_contexts = {
         "ChoirStaff": core.StaffGroup,
         "GrandStaff": core.StaffGroup,
         "PianoStaff": core.StaffGroup,
         "Score": core.Score,
         "Staff": core.Staff,
         "StaffGroup": core.StaffGroup,
         "Voice": core.Voice,
     }
     lilypond_type = context
     if context in known_contexts:
         context = known_contexts[context]([])
     else:
         message = "context type {!r} not supported."
         message = message.format(context)
         raise Exception(message)
     if lilypond_type in ("GrandStaff", "PianoStaff"):
         context.lilypond_type = lilypond_type
     if optional_id is not None:
         context.name = optional_id
     if optional_context_mod is not None:
         for x in optional_context_mod:
             print(x)
         # TODO: impelement context mods on contexts
         pass
     context.simultaneous = music.simultaneous
     # add children
     while len(music):
         component = music.pop(0)
         context.append(component)
     for wrapper in music._wrappers:
         attach(wrapper, context)
     return context
Exemplo n.º 6
0
Arquivo: Leaf.py Projeto: Abjad/abjad
 def _copy_override_and_set_from_leaf(self, leaf):
     if getattr(leaf, "_overrides", None) is not None:
         self._overrides = copy.copy(override(leaf))
     if getattr(leaf, "_lilypond_setting_name_manager", None) is not None:
         self._lilypond_setting_name_manager = copy.copy(setting(leaf))
     new_wrappers = []
     for wrapper in leaf._wrappers:
         new_wrapper = copy.copy(wrapper)
         new_wrappers.append(new_wrapper)
     for new_wrapper in new_wrappers:
         attach(new_wrapper, self)
Exemplo n.º 7
0
    def __illustrate__(self):
        """
        Illustrates articulation.

        Returns LilyPond file.
        """
        note = abjad.Note("c'4")
        articulation = copy.copy(self)
        attach(articulation, note)
        lilypond_file = abjad.LilyPondFile.new(note)
        return lilypond_file
Exemplo n.º 8
0
    def __illustrate__(self):
        """
        Illustrates articulation.

        Returns LilyPond file.
        """
        note = abjad.Note("c'4")
        articulation = copy.copy(self)
        attach(articulation, note)
        lilypond_file = abjad.LilyPondFile.new(note)
        return lilypond_file
Exemplo n.º 9
0
 def _copy_override_and_set_from_leaf(self, leaf):
     if getattr(leaf, '_overrides', None) is not None:
         self._overrides = copy.copy(override(leaf))
     if getattr(leaf, '_lilypond_setting_name_manager', None) is not None:
         self._lilypond_setting_name_manager = copy.copy(setting(leaf))
     new_wrappers = []
     for wrapper in leaf._wrappers:
         new_wrapper = copy.copy(wrapper)
         new_wrappers.append(new_wrapper)
     for new_wrapper in new_wrappers:
         attach(new_wrapper, self)
Exemplo n.º 10
0
    def _attach_lilypond_one_voice(self):
        from .Voice import Voice

        anchor_leaf = self._get_on_beat_anchor_leaf()
        anchor_voice = abjad_inspect(anchor_leaf).parentage().get(Voice)
        final_anchor_leaf = abjad_inspect(anchor_voice).leaf(-1)
        next_leaf = abjad_inspect(final_anchor_leaf).leaf(1)
        literal = LilyPondLiteral(r"\oneVoice")
        if abjad_inspect(next_leaf).has_indicator(literal):
            return
        site = "abjad.OnBeatGraceContainer._attach_lilypond_one_voice()"
        tag = Tag(site)
        attach(literal, next_leaf, tag=tag)
Exemplo n.º 11
0
 def __copy__(self, *arguments):
     """
     Shallow copies leaf.
     """
     new = Component.__copy__(self, *arguments)
     new.multiplier = self.multiplier
     before_grace_container = self._before_grace_container
     if before_grace_container is not None:
         new_grace_container = before_grace_container._copy_with_children()
         attach(new_grace_container, new)
     after_grace_container = self._after_grace_container
     if after_grace_container is not None:
         new_after_grace_container = after_grace_container._copy_with_children(
         )
         attach(new_after_grace_container, new)
     return new
Exemplo n.º 12
0
    def __copy__(self, *arguments):
        """
        Shallow copies leaf.

        Returns new leaf.
        """
        new = Component.__copy__(self, *arguments)
        grace_container = self._grace_container
        if grace_container is not None:
            new_grace_container = grace_container._copy_with_children()
            attach(new_grace_container, new)
        after_grace_container = self._after_grace_container
        if after_grace_container is not None:
            new_after_grace_container = \
                after_grace_container._copy_with_children()
            attach(new_after_grace_container, new)
        return new
Exemplo n.º 13
0
    def _attach_lilypond_one_voice(self):
        from .Voice import Voice

        anchor_leaf = self._get_on_beat_anchor_leaf()
        anchor_voice = abjad_inspect(anchor_leaf).parentage().get(Voice)
        final_anchor_leaf = abjad_inspect(anchor_voice).leaf(-1)
        next_leaf = abjad_inspect(final_anchor_leaf).leaf(1)
        literal = LilyPondLiteral(r"\oneVoice", format_slot="absolute_before")
        if abjad_inspect(next_leaf).has_indicator(literal):
            return
        if isinstance(next_leaf._parent, OnBeatGraceContainer):
            return
        if next_leaf._parent._is_on_beat_anchor_voice():
            return
        site = "abjad.OnBeatGraceContainer._attach_lilypond_one_voice()"
        tag = Tag(site)
        tag = tag.append(abjad_tags.ONE_VOICE_COMMAND)
        attach(literal, next_leaf, tag=tag)
Exemplo n.º 14
0
Arquivo: Leaf.py Projeto: Abjad/abjad
    def __copy__(self, *arguments):
        """
        Shallow copies leaf.

        Returns new leaf.
        """
        new = Component.__copy__(self, *arguments)
        new.multiplier = self.multiplier
        grace_container = self._grace_container
        if grace_container is not None:
            new_grace_container = grace_container._copy_with_children()
            attach(new_grace_container, new)
        after_grace_container = self._after_grace_container
        if after_grace_container is not None:
            new_after_grace_container = (
                after_grace_container._copy_with_children()
            )
            attach(new_after_grace_container, new)
        return new
Exemplo n.º 15
0
 def _construct_context_specced_music(
     self, context, optional_id, optional_context_mod, music
 ):
     known_contexts = {
         "ChoirStaff": core.StaffGroup,
         "GrandStaff": core.StaffGroup,
         "PianoStaff": core.StaffGroup,
         "Score": core.Score,
         "Staff": core.Staff,
         "StaffGroup": core.StaffGroup,
         "Voice": core.Voice,
     }
     lilypond_type = context
     if context in known_contexts:
         context = known_contexts[context]([])
     else:
         message = "context type {!r} not supported."
         message = message.format(context)
         raise Exception(message)
     if lilypond_type in ("GrandStaff", "PianoStaff"):
         context.lilypond_type = lilypond_type
     if optional_id is not None:
         context.name = optional_id
     if optional_context_mod is not None:
         for x in optional_context_mod:
             print(x)
         # TODO: impelement context mods on contexts
         pass
     context.is_simultaneous = music.is_simultaneous
     # add children
     while len(music):
         component = music.pop(0)
         context.append(component)
     for wrapper in music._wrappers:
         attach(wrapper, context)
     return context
Exemplo n.º 16
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)
Exemplo n.º 17
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)
Exemplo n.º 18
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
Exemplo n.º 19
0
Arquivo: Leaf.py Projeto: Abjad/abjad
    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
Exemplo n.º 20
0
def on_beat_grace_container(
    contents,
    anchor_voice_selection,
    *,
    anchor_voice_number=2,
    do_not_beam=None,
    do_not_slash=None,
    do_not_slur=None,
    do_not_stop_polyphony=None,
    font_size=-3,
    grace_voice_number=1,
    leaf_duration=None,
):
    r"""
    Makes on-beat grace container and wraps around ``selection``.

    ..  container:: example

        GRACE NOTES ABOVE.

        Note-to-note anchor:

        >>> music_voice = abjad.Voice("c'4 d' e' f'", name="Music_Voice")
        >>> string = "g'8 a' b' c'' d'' c'' b' a' b' c'' d''"
        >>> result = abjad.on_beat_grace_container(
        ...     string, music_voice[1:3], leaf_duration=(1, 30)
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    c'4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceOne %! abjad.on_beat_grace_container(3)
                            <
                                \tweak font-size #0
                                \tweak transparent ##t
                                d'
                                g'
                            >8 * 4/15
                            [
                            (
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            c''8 * 4/15
                            b'8 * 4/15
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceTwo %! abjad.on_beat_grace_container(4)
                            d'4
                            e'4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    f'4
                }
            }

        Note-to-chord anchor:

        >>> music_voice = abjad.Voice(
        ...     "<a c'>4 <b d'> <c' e'> <d' f'>", name="Music_Voice"
        ... )
        >>> string = "g'8 a' b' c'' d'' c'' b' a' b' c'' d''"
        >>> result = abjad.on_beat_grace_container(
        ...     string, music_voice[1:3], leaf_duration=(1, 30)
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    <a c'>4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceOne %! abjad.on_beat_grace_container(3)
                            <
                                \tweak font-size #0
                                \tweak transparent ##t
                                d'
                                g'
                            >8 * 4/15
                            [
                            (
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            c''8 * 4/15
                            b'8 * 4/15
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceTwo %! abjad.on_beat_grace_container(4)
                            <b d'>4
                            <c' e'>4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    <d' f'>4
                }
            }

        Chord-to-note anchor:

        >>> music_voice = abjad.Voice("c'4 d' e' f'", name="Music_Voice")
        >>> string = "<g' b'>8 a' b' c'' d'' c'' b' a' b' c'' d''"
        >>> result = abjad.on_beat_grace_container(
        ...     string, music_voice[1:3], leaf_duration=(1, 30)
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    c'4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceOne %! abjad.on_beat_grace_container(3)
                            <
                                \tweak font-size #0
                                \tweak transparent ##t
                                d'
                                g'
                                b'
                            >8 * 4/15
                            [
                            (
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            c''8 * 4/15
                            b'8 * 4/15
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceTwo %! abjad.on_beat_grace_container(4)
                            d'4
                            e'4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    f'4
                }
            }

        Chord-to-chord anchor:

        >>> music_voice = abjad.Voice(
        ...     "<a c'>4 <b d'> <c' e'> <d' f'>", name="Music_Voice"
        ... )
        >>> string = "<g' b'>8 a' b' c'' d'' c'' b' a' b' c'' d''"
        >>> result = abjad.on_beat_grace_container(
        ...     string, music_voice[1:3], leaf_duration=(1, 30)
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    <a c'>4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceOne %! abjad.on_beat_grace_container(3)
                            <
                                \tweak font-size #0
                                \tweak transparent ##t
                                d'
                                g'
                                b'
                            >8 * 4/15
                            [
                            (
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            c''8 * 4/15
                            b'8 * 4/15
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceTwo %! abjad.on_beat_grace_container(4)
                            <b d'>4
                            <c' e'>4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    <d' f'>4
                }
            }

    ..  container:: example

        GRACE NOTES BELOW.

        Note-to-note anchor:

        >>> music_voice = abjad.Voice("c'4 d' e' f'", name="Music_Voice")
        >>> string = "g8 a b c' d' c' b a b c' d'"
        >>> result = abjad.on_beat_grace_container(
        ...     string,
        ...     music_voice[1:3],
        ...     anchor_voice_number=1,
        ...     grace_voice_number=2,
        ...     leaf_duration=(1, 30),
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    c'4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceTwo %! abjad.on_beat_grace_container(3)
                            <
                                g
                                \tweak font-size #0
                                \tweak transparent ##t
                                d'
                            >8 * 4/15
                            [
                            (
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            c'8 * 4/15
                            b8 * 4/15
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceOne %! abjad.on_beat_grace_container(4)
                            d'4
                            e'4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    f'4
                }
            }

        Note-to-chord anchor:

        >>> music_voice = abjad.Voice(
        ...     "<c' e'>4 <d' f'> <e' g'> <f' a'>", name="Music_Voice"
        ... )
        >>> string = "g8 a b c' d' c' b a b c' d'"
        >>> result = abjad.on_beat_grace_container(
        ...     string,
        ...     music_voice[1:3],
        ...     anchor_voice_number=1,
        ...     grace_voice_number=2,
        ...     leaf_duration=(1, 30),
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    <c' e'>4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceTwo %! abjad.on_beat_grace_container(3)
                            <
                                g
                                \tweak font-size #0
                                \tweak transparent ##t
                                f'
                            >8 * 4/15
                            [
                            (
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            c'8 * 4/15
                            b8 * 4/15
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceOne %! abjad.on_beat_grace_container(4)
                            <d' f'>4
                            <e' g'>4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    <f' a'>4
                }
            }

        Chord-to-note anchor:

        >>> music_voice = abjad.Voice("c'4 d' e' f'", name="Music_Voice")
        >>> string = "<e g>8 a b c' d' c' b a b c' d'"
        >>> result = abjad.on_beat_grace_container(
        ...     string,
        ...     music_voice[1:3],
        ...     anchor_voice_number=1,
        ...     grace_voice_number=2,
        ...     leaf_duration=(1, 30),
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    c'4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceTwo %! abjad.on_beat_grace_container(3)
                            <
                                e
                                g
                                \tweak font-size #0
                                \tweak transparent ##t
                                d'
                            >8 * 4/15
                            [
                            (
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            c'8 * 4/15
                            b8 * 4/15
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceOne %! abjad.on_beat_grace_container(4)
                            d'4
                            e'4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    f'4
                }
            }

        Chord-to-chord anchor:

        >>> music_voice = abjad.Voice(
        ...     "<c' e'>4 <d' f'> <e' g'> <f' a'>", name="Music_Voice"
        ... )
        >>> string = "<e g>8 a b c' d' c' b a b c' d'"
        >>> result = abjad.on_beat_grace_container(
        ...     string,
        ...     music_voice[1:3],
        ...     anchor_voice_number=1,
        ...     grace_voice_number=2,
        ...     leaf_duration=(1, 30),
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    <c' e'>4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceTwo %! abjad.on_beat_grace_container(3)
                            <
                                e
                                g
                                \tweak font-size #0
                                \tweak transparent ##t
                                f'
                            >8 * 4/15
                            [
                            (
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            c'8 * 4/15
                            b8 * 4/15
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceOne %! abjad.on_beat_grace_container(4)
                            <d' f'>4
                            <e' g'>4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    <f' a'>4
                }
            }

    ..  container:: example

        Raises exception when duration of on-beat grace container exceeds
        duration of anchor container:

        >>> music_voice = abjad.Voice("c'4 d' e' f'", name="Music_Voice")
        >>> string = "g'8 a' b' c'' d'' c'' b' a' b' c'' d''"
        >>> result = abjad.on_beat_grace_container(
        ...     string, music_voice[1:2], leaf_duration=(1, 8)
        ... )
        Traceback (most recent call last):
            ...
        Exception: grace Duration(11, 8) exceeds anchor Duration(1, 4).

    """
    from .Container import Container
    from .Selection import Selection
    from .Voice import Voice
    from abjad.spanners import beam
    from abjad.spanners import slur

    def _site(n):
        return Tag(f"abjad.on_beat_grace_container({n})")

    assert isinstance(anchor_voice_selection, Selection)
    if not anchor_voice_selection.are_contiguous_same_parent(
            ignore_before_after_grace=True):
        message = "selection must be contiguous in same parent:\n"
        message += f"   {repr(anchor_voice_selection)}"
        raise Exception(message)
    on_beat_grace_container = OnBeatGraceContainer(contents,
                                                   leaf_duration=leaf_duration)
    if not isinstance(anchor_voice_selection, Selection):
        raise Exception(f"must be selection:\n {repr(anchor_voice_selection)}")
    anchor_leaf = abjad_inspect(anchor_voice_selection).leaf(0)
    anchor_voice = abjad_inspect(anchor_leaf).parentage().get(Voice)
    if anchor_voice.name is None:
        raise Exception(
            f"anchor voice must be named:\n   {repr(anchor_voice)}")
    anchor_voice_insert = Voice(name=anchor_voice.name)
    mutate(anchor_voice_selection).wrap(anchor_voice_insert)
    container = Container(simultaneous=True)
    mutate(anchor_voice_insert).wrap(container)
    container.insert(0, on_beat_grace_container)
    on_beat_grace_container._match_anchor_leaf()
    on_beat_grace_container._set_leaf_durations()
    insert_duration = abjad_inspect(anchor_voice_insert).duration()
    grace_container_duration = abjad_inspect(
        on_beat_grace_container).duration()
    if insert_duration < grace_container_duration:
        message = f"grace {repr(grace_container_duration)}"
        message += f" exceeds anchor {repr(insert_duration)}."
        raise Exception(message)
    if font_size is not None:
        string = rf"\set fontSize = #{font_size}"
        literal = LilyPondLiteral(string)
        attach(literal, on_beat_grace_container, tag=_site(1))
    if not do_not_beam:
        beam(on_beat_grace_container[:])
    if not do_not_slash:
        literal = LilyPondLiteral(r"\slash")
        attach(literal, on_beat_grace_container[0], tag=_site(2))
    if not do_not_slur:
        slur(on_beat_grace_container[:])
    voice_number_to_string = {
        1: r"\voiceOne",
        2: r"\voiceTwo",
        3: r"\voiceThree",
        4: r"\voiceFour",
    }
    first_grace = abjad_inspect(on_beat_grace_container).leaf(0)
    one_voice_literal = LilyPondLiteral(r"\oneVoice",
                                        format_slot="absolute_before")
    string = voice_number_to_string.get(grace_voice_number, None)
    if string is not None:
        literal
        detach(one_voice_literal, anchor_leaf)
        attach(LilyPondLiteral(string), first_grace, tag=_site(3))
    string = voice_number_to_string.get(anchor_voice_number, None)
    if string is not None:
        detach(one_voice_literal, anchor_leaf)
        attach(LilyPondLiteral(string), anchor_leaf, tag=_site(4))
    if not do_not_stop_polyphony:
        last_anchor_leaf = abjad_inspect(anchor_voice_selection).leaf(-1)
        next_leaf = abjad_inspect(last_anchor_leaf).leaf(1)
        if next_leaf is not None:
            literal = LilyPondLiteral(r"\oneVoice",
                                      format_slot="absolute_before")
            attach(literal, next_leaf, tag=_site(5))
    return on_beat_grace_container
Exemplo n.º 21
0
    def rhythm(
        class_,
        selections,
        divisions=None,
        attach_lilypond_voice_commands=None,
        implicit_scaling=None,
        pitched_staff=None,
        simultaneous_selections=None,
        time_signatures=None,
        ):
        r"""
        Makes rhythm-styled LilyPond file.

        ..  container:: example

            Makes rhythmic staff:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.attach(abjad.Beam(), selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> score = lilypond_file[abjad.Score]
                >>> abjad.f(score)
                \new Score
                <<
                    \new GlobalContext
                    {
                        {   % measure
                            \time 3/4
                            s1 * 3/4
                        }   % measure
                        {   % measure
                            \time 4/8
                            s1 * 1/2
                        }   % measure
                        {   % measure
                            \time 1/4
                            s1 * 1/4
                        }   % measure
                    }
                    \new RhythmicStaff
                    {
                        {   % measure
                            \time 3/4
                            c'8
                            [
                            c'8
                            c'8
                            c'8
                            c'8
                            c'8
                            ]
                        }   % measure
                        {   % measure
                            \time 4/8
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            ]
                        }   % measure
                        {   % measure
                            \time 1/4
                            c'8
                            [
                            c'8
                            ]
                        }   % measure
                    }
                >>

        ..  container:: example

            Set time signatures explicitly:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.attach(abjad.Beam(), selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     [(6, 8), (4, 8), (2, 8)],
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> score = lilypond_file[abjad.Score]
                >>> abjad.f(score)
                \new Score
                <<
                    \new GlobalContext
                    {
                        {   % measure
                            \time 6/8
                            s1 * 3/4
                        }   % measure
                        {   % measure
                            \time 4/8
                            s1 * 1/2
                        }   % measure
                        {   % measure
                            \time 2/8
                            s1 * 1/4
                        }   % measure
                    }
                    \new RhythmicStaff
                    {
                        {   % measure
                            \time 6/8
                            c'8
                            [
                            c'8
                            c'8
                            c'8
                            c'8
                            c'8
                            ]
                        }   % measure
                        {   % measure
                            \time 4/8
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            ]
                        }   % measure
                        {   % measure
                            \time 2/8
                            c'8
                            [
                            c'8
                            ]
                        }   % measure
                    }
                >>

        ..  container:: example

            Makes pitched staff:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.attach(abjad.Beam(), selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     pitched_staff=True,
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(lilypond_file[abjad.Score])
                \new Score
                <<
                    \new GlobalContext
                    {
                        {   % measure
                            \time 3/4
                            s1 * 3/4
                        }   % measure
                        {   % measure
                            \time 4/8
                            s1 * 1/2
                        }   % measure
                        {   % measure
                            \time 1/4
                            s1 * 1/4
                        }   % measure
                    }
                    \new Staff
                    {
                        {   % measure
                            \time 3/4
                            c'8
                            [
                            c'8
                            c'8
                            c'8
                            c'8
                            c'8
                            ]
                        }   % measure
                        {   % measure
                            \time 4/8
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            ]
                        }   % measure
                        {   % measure
                            \time 1/4
                            c'8
                            [
                            c'8
                            ]
                        }   % measure
                    }
                >>

        ..  container:: example

            Makes simultaneous voices:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.attach(abjad.Beam(), selection[:])
            ...
            >>> for note in abjad.iterate(selections).components(abjad.Note):
            ...     note.written_pitch = abjad.NamedPitch("e'")
            ...
            >>> selection_1 = selections[0] + selections[1] + selections[2]
            >>> selections = [
            ...     maker(12 * [0], [(1, 16)]),
            ...     maker(16 * [0], [(1, 32)]),
            ...     maker(4 * [0], [(1, 16)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.attach(abjad.Beam(), selection[:])
            ...
            >>> selection_2 = selections[0] + selections[1] + selections[2]
            >>> selections = {
            ...     'Voice 1': selection_1,
            ...     'Voice 2': selection_2,
            ... }
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     )
            >>> voice_1 = lilypond_file['Voice 1']
            >>> abjad.attach(abjad.LilyPondLiteral(r'\voiceOne'), voice_1)
            >>> voice_2 = lilypond_file['Voice 2']
            >>> abjad.attach(abjad.LilyPondLiteral(r'\voiceTwo'), voice_2)
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(lilypond_file[abjad.Score])
                \new Score
                <<
                    \new GlobalContext
                    {
                        {   % measure
                            \time 3/4
                            s1 * 3/4
                        }   % measure
                        {   % measure
                            \time 4/8
                            s1 * 1/2
                        }   % measure
                        {   % measure
                            \time 1/4
                            s1 * 1/4
                        }   % measure
                    }
                    \new Staff
                    <<
                        \context Voice = "Voice 1"
                        {
                            \voiceOne
                            e'8
                            [
                            e'8
                            e'8
                            e'8
                            e'8
                            e'8
                            ]
                            e'16
                            [
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            ]
                            e'8
                            [
                            e'8
                            ]
                        }
                        \context Voice = "Voice 2"
                        {
                            \voiceTwo
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            ]
                            c'32
                            [
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            ]
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            ]
                        }
                    >>
                >>

        Returns LilyPond file.
        """
        if isinstance(selections, list):
            for selection in selections:
                if not isinstance(selection, Selection):
                    message = f'must be selection: {selection!r}.'
                    raise TypeError(message)
        elif isinstance(selections, dict):
            for selection in selections.values():
                if not isinstance(selection, Selection):
                    message = f'must be selection: {selection!r}.'
                    raise TypeError(message)
        else:
            message = f'must be list or dictionary: {selections!r}.'
            raise TypeError(message)
        score = Score()
        lilypond_file = LilyPondFile.new(
            score,
            includes=['default.ily', 'rhythm-maker-docs.ily'],
            )
        if pitched_staff is None:
            if isinstance(selections, list):
                selections_ = selections
            elif isinstance(selections, dict):
                selections_ = selections.values()
            else:
                raise TypeError(selections)
            for note in iterate(selections_).leaves(Note):
                if note.written_pitch != NamedPitch("c'"):
                    pitched_staff = True
                    break
        if isinstance(selections, list):
            if divisions is None:
                duration = abjad_inspect(selections).duration()
                divisions = [duration]
            time_signatures = time_signatures or divisions
            maker = MeasureMaker(implicit_scaling=implicit_scaling)
            measures = maker(time_signatures)
            if pitched_staff:
                staff = Staff(measures)
            else:
                staff = Staff(measures, lilypond_type='RhythmicStaff')
            selections = sequence(selections).flatten(depth=-1)
            selections_ = copy.deepcopy(selections)
            try:
                agent = mutate(staff)
                measures = agent.replace_measure_contents(selections)
            except StopIteration:
                if pitched_staff:
                    staff = Staff(selections_)
                else:
                    staff = Staff(
                        selections_,
                        lilypond_type='RhythmicStaff',
                        )
        elif isinstance(selections, dict):
            voices = []
            for voice_name in sorted(selections):
                selections_ = selections[voice_name]
                selections_ = sequence(selections_).flatten(depth=-1)
                selections_ = copy.deepcopy(selections_)
                voice = Voice(selections_, name=voice_name)
                if attach_lilypond_voice_commands:
                    voice_name_to_command_string = {
                        'Voice 1': 'voiceOne',
                        'Voice 2': 'voiceTwo',
                        'Voice 3': 'voiceThree',
                        'Voice 4': 'voiceFour',
                        }
                    command_string = voice_name_to_command_string.get(
                        voice_name,
                        )
                    if command_string:
                        command = LilyPondLiteral('\\' + command_string)
                        attach(command, voice)
                voices.append(voice)
            staff = Staff(voices, is_simultaneous=True)
            if divisions is None:
                duration = abjad_inspect(staff).duration()
                divisions = [duration]
        else:
            message = 'must be list or dictionary of selections:'
            message += f' {selections!r}.'
            raise TypeError(message)
        score.append(staff)
        assert isinstance(divisions, collections.Sequence), repr(divisions)
        time_signatures = time_signatures or divisions
        context = Context(lilypond_type='GlobalContext')
        maker = MeasureMaker(implicit_scaling=implicit_scaling)
        measures = maker(time_signatures)
        context.extend(measures)
        score.insert(0, context)
        return lilypond_file
Exemplo n.º 22
0
 def _construct_sequential_music(self, music):
     # indicator sorting could be rewritten into a single list using tuplets
     # with t[0] being 'forward' or 'backward' and t[1] being the indicator
     # as this better preserves attachment order. Not clear if we need it.
     container = core.Container()
     previous_leaf = None
     apply_forward = []
     apply_backward = []
     # sort events into forward or backwards attaching
     # and attach them to the proper leaf
     for x in music:
         if isinstance(x, core.Component) and not isinstance(
             x, core.GraceContainer
         ):
             for indicator in apply_forward:
                 attach(indicator, x)
             if previous_leaf:
                 for indicator in apply_backward:
                     attach(indicator, previous_leaf)
             else:
                 for indicator in apply_backward:
                     attach(indicator, x)
             apply_forward[:] = []
             apply_backward[:] = []
             previous_leaf = x
             container.append(x)
         else:
             if isinstance(x, (abjad_indicators.BarLine,)):
                 apply_backward.append(x)
             elif isinstance(
                 x, abjad_indicators.LilyPondLiteral
             ) and x.name in (r"\break", r"\breathe", r"\pageBreak"):
                 apply_backward.append(x)
             else:
                 apply_forward.append(x)
     # attach remaining events to last leaf
     # or to the container itself if there were no leaves
     if previous_leaf:
         for indicator in apply_forward:
             attach(indicator, previous_leaf)
         for indicator in apply_backward:
             attach(indicator, previous_leaf)
     else:
         for indicator in apply_forward:
             attach(indicator, container)
         for indicator in apply_backward:
             attach(indicator, container)
     return container
Exemplo n.º 23
0
    def rhythm(
        class_,
        selections,
        divisions=None,
        attach_lilypond_voice_commands=None,
        implicit_scaling=None,
        pitched_staff=None,
        simultaneous_selections=None,
        time_signatures=None,
    ):
        r"""
        Makes rhythm-styled LilyPond file.

        ..  container:: example

            Makes rhythmic staff:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> score = lilypond_file[abjad.Score]
                >>> abjad.f(score)
                \new Score
                <<
                    \new GlobalContext
                    {
                        \time 3/4
                        s1 * 3/4
                        \time 4/8
                        s1 * 1/2
                        \time 1/4
                        s1 * 1/4
                    }
                    \new RhythmicStaff
                    {
                        c'8
                        [
                        c'8
                        c'8
                        c'8
                        c'8
                        c'8
                        ]
                        c'16
                        [
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        ]
                        c'8
                        [
                        c'8
                        ]
                    }
                >>

        ..  container:: example

            Set time signatures explicitly:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     [(6, 8), (4, 8), (2, 8)],
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> score = lilypond_file[abjad.Score]
                >>> abjad.f(score)
                \new Score
                <<
                    \new GlobalContext
                    {
                        \time 6/8
                        s1 * 3/4
                        \time 4/8
                        s1 * 1/2
                        \time 2/8
                        s1 * 1/4
                    }
                    \new RhythmicStaff
                    {
                        c'8
                        [
                        c'8
                        c'8
                        c'8
                        c'8
                        c'8
                        ]
                        c'16
                        [
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        ]
                        c'8
                        [
                        c'8
                        ]
                    }
                >>

        ..  container:: example

            Makes pitched staff:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     pitched_staff=True,
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(lilypond_file[abjad.Score])
                \new Score
                <<
                    \new GlobalContext
                    {
                        \time 3/4
                        s1 * 3/4
                        \time 4/8
                        s1 * 1/2
                        \time 1/4
                        s1 * 1/4
                    }
                    \new Staff
                    {
                        c'8
                        [
                        c'8
                        c'8
                        c'8
                        c'8
                        c'8
                        ]
                        c'16
                        [
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        ]
                        c'8
                        [
                        c'8
                        ]
                    }
                >>

        ..  container:: example

            Makes simultaneous voices:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> for note in abjad.iterate(selections).components(abjad.Note):
            ...     note.written_pitch = abjad.NamedPitch("e'")
            ...
            >>> selection_1 = selections[0] + selections[1] + selections[2]
            >>> selections = [
            ...     maker(12 * [0], [(1, 16)]),
            ...     maker(16 * [0], [(1, 32)]),
            ...     maker(4 * [0], [(1, 16)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> selection_2 = selections[0] + selections[1] + selections[2]
            >>> selections = {
            ...     'Voice_1': selection_1,
            ...     'Voice_2': selection_2,
            ... }
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     )
            >>> voice_1 = lilypond_file['Voice_1']
            >>> abjad.attach(abjad.LilyPondLiteral(r'\voiceOne'), voice_1)
            >>> voice_2 = lilypond_file['Voice_2']
            >>> abjad.attach(abjad.LilyPondLiteral(r'\voiceTwo'), voice_2)
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(lilypond_file[abjad.Score])
                \new Score
                <<
                    \new GlobalContext
                    {
                        s1 * 3/4
                        s1 * 1/2
                        s1 * 1/4
                    }
                    \new Staff
                    <<
                        \context Voice = "Voice_1"
                        {
                            \voiceOne
                            e'8
                            [
                            e'8
                            e'8
                            e'8
                            e'8
                            e'8
                            ]
                            e'16
                            [
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            ]
                            e'8
                            [
                            e'8
                            ]
                        }
                        \context Voice = "Voice_2"
                        {
                            \voiceTwo
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            ]
                            c'32
                            [
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            ]
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            ]
                        }
                    >>
                >>

        Returns LilyPond file.
        """
        if isinstance(selections, list):
            for selection in selections:
                if not isinstance(selection, Selection):
                    raise TypeError(f"must be selection: {selection!r}.")
        elif isinstance(selections, dict):
            for selection in selections.values():
                if not isinstance(selection, Selection):
                    raise TypeError(f"must be selection: {selection!r}.")
        else:
            raise TypeError(f"must be list or dictionary: {selections!r}.")
        score = Score()
        lilypond_file = LilyPondFile.new(
            score, includes=["default.ily", "rhythm-maker-docs.ily"]
        )
        if pitched_staff is None:
            if isinstance(selections, list):
                selections_ = selections
            elif isinstance(selections, dict):
                selections_ = selections.values()
            else:
                raise TypeError(selections)
            for note in iterate(selections_).leaves(Note):
                if note.written_pitch != NamedPitch("c'"):
                    pitched_staff = True
                    break
        if isinstance(selections, list):
            if divisions is None:
                duration = abjad_inspect(selections).duration()
                divisions = [duration]
            time_signatures = time_signatures or divisions
            time_signatures = [TimeSignature(_) for _ in time_signatures]
            if pitched_staff:
                staff = Staff()
            else:
                staff = Staff(lilypond_type="RhythmicStaff")
            staff.extend(selections)
        elif isinstance(selections, dict):
            voices = []
            for voice_name in sorted(selections):
                selections_ = selections[voice_name]
                selections_ = sequence(selections_).flatten(depth=-1)
                selections_ = copy.deepcopy(selections_)
                voice = Voice(selections_, name=voice_name)
                if attach_lilypond_voice_commands:
                    voice_name_to_command_string = {
                        "Voice_1": "voiceOne",
                        "Voice_2": "voiceTwo",
                        "Voice_3": "voiceThree",
                        "Voice_4": "voiceFour",
                    }
                    command_string = voice_name_to_command_string.get(
                        voice_name
                    )
                    if command_string:
                        command = LilyPondLiteral("\\" + command_string)
                        attach(command, voice)
                voices.append(voice)
            staff = Staff(voices, is_simultaneous=True)
            if divisions is None:
                duration = abjad_inspect(staff).duration()
                divisions = [duration]
        else:
            message = "must be list or dictionary of selections:"
            message += f" {selections!r}."
            raise TypeError(message)
        score.append(staff)
        assert isinstance(divisions, collections.abc.Sequence), repr(divisions)
        time_signatures = time_signatures or divisions
        context = Context(lilypond_type="GlobalContext")
        skips = []
        for time_signature in time_signatures:
            skip = Skip(1)
            skip.multiplier = time_signature
            attach(time_signature, skip, context="Score")
            skips.append(skip)
        context.extend(skips)
        score.insert(0, context)
        return lilypond_file
Exemplo n.º 24
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
Exemplo n.º 25
0
    def rhythm(
        class_,
        selections,
        divisions=None,
        attach_lilypond_voice_commands=None,
        implicit_scaling=None,
        pitched_staff=None,
        simultaneous_selections=None,
        time_signatures=None,
    ):
        r"""
        Makes rhythm-styled LilyPond file.

        ..  container:: example

            Makes rhythmic staff:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> score = lilypond_file[abjad.Score]
                >>> abjad.f(score)
                \new Score
                <<
                    \new GlobalContext
                    {
                        \time 3/4
                        s1 * 3/4
                        \time 4/8
                        s1 * 1/2
                        \time 1/4
                        s1 * 1/4
                    }
                    \new RhythmicStaff
                    {
                        c'8
                        [
                        c'8
                        c'8
                        c'8
                        c'8
                        c'8
                        ]
                        c'16
                        [
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        ]
                        c'8
                        [
                        c'8
                        ]
                    }
                >>

        ..  container:: example

            Set time signatures explicitly:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     [(6, 8), (4, 8), (2, 8)],
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> score = lilypond_file[abjad.Score]
                >>> abjad.f(score)
                \new Score
                <<
                    \new GlobalContext
                    {
                        \time 6/8
                        s1 * 3/4
                        \time 4/8
                        s1 * 1/2
                        \time 2/8
                        s1 * 1/4
                    }
                    \new RhythmicStaff
                    {
                        c'8
                        [
                        c'8
                        c'8
                        c'8
                        c'8
                        c'8
                        ]
                        c'16
                        [
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        ]
                        c'8
                        [
                        c'8
                        ]
                    }
                >>

        ..  container:: example

            Makes pitched staff:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     pitched_staff=True,
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(lilypond_file[abjad.Score])
                \new Score
                <<
                    \new GlobalContext
                    {
                        \time 3/4
                        s1 * 3/4
                        \time 4/8
                        s1 * 1/2
                        \time 1/4
                        s1 * 1/4
                    }
                    \new Staff
                    {
                        c'8
                        [
                        c'8
                        c'8
                        c'8
                        c'8
                        c'8
                        ]
                        c'16
                        [
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        ]
                        c'8
                        [
                        c'8
                        ]
                    }
                >>

        ..  container:: example

            Makes simultaneous voices:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> for note in abjad.iterate(selections).components(abjad.Note):
            ...     note.written_pitch = abjad.NamedPitch("e'")
            ...
            >>> selection_1 = selections[0] + selections[1] + selections[2]
            >>> selections = [
            ...     maker(12 * [0], [(1, 16)]),
            ...     maker(16 * [0], [(1, 32)]),
            ...     maker(4 * [0], [(1, 16)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> selection_2 = selections[0] + selections[1] + selections[2]
            >>> selections = {
            ...     'Voice_1': selection_1,
            ...     'Voice_2': selection_2,
            ... }
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     )
            >>> voice_1 = lilypond_file['Voice_1']
            >>> literal = abjad.LilyPondLiteral(r'\voiceOne', "opening")
            >>> abjad.attach(literal, voice_1)
            >>> voice_2 = lilypond_file['Voice_2']
            >>> literal = abjad.LilyPondLiteral(r'\voiceTwo', "opening")
            >>> abjad.attach(literal, voice_2)
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(lilypond_file[abjad.Score])
                \new Score
                <<
                    \new GlobalContext
                    {
                        s1 * 3/4
                        s1 * 1/2
                        s1 * 1/4
                    }
                    \new Staff
                    <<
                        \context Voice = "Voice_1"
                        {
                            \voiceOne
                            e'8
                            [
                            e'8
                            e'8
                            e'8
                            e'8
                            e'8
                            ]
                            e'16
                            [
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            ]
                            e'8
                            [
                            e'8
                            ]
                        }
                        \context Voice = "Voice_2"
                        {
                            \voiceTwo
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            ]
                            c'32
                            [
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            ]
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            ]
                        }
                    >>
                >>

        Returns LilyPond file.
        """
        if isinstance(selections, Selection):
            pass
        elif isinstance(selections, list):
            for selection in selections:
                if not isinstance(selection, Selection):
                    raise TypeError(f"must be selection: {selection!r}.")
        elif isinstance(selections, dict):
            for selection in selections.values():
                if not isinstance(selection, Selection):
                    raise TypeError(f"must be selection: {selection!r}.")
        else:
            raise TypeError(f"must be list or dictionary: {selections!r}.")
        score = Score()
        lilypond_file = LilyPondFile.new(
            score, includes=["default.ily", "rhythm-maker-docs.ily"]
        )
        if pitched_staff is None:
            if isinstance(selections, (list, Selection)):
                selections_ = selections
            elif isinstance(selections, dict):
                selections_ = selections.values()
            else:
                raise TypeError(selections)
            for note in select(selections_).notes():
                if note.written_pitch != NamedPitch("c'"):
                    pitched_staff = True
                    break
            chords = select(selections_).chords()
            if chords:
                pitched_staff = True
        if isinstance(selections, (list, Selection)):
            if divisions is None:
                duration = abjad_inspect(selections).duration()
                divisions = [duration]
            time_signatures = time_signatures or divisions
            time_signatures = [TimeSignature(_) for _ in time_signatures]
            if pitched_staff:
                staff = Staff()
            else:
                staff = Staff(lilypond_type="RhythmicStaff")
            staff.extend(selections)
        elif isinstance(selections, dict):
            voices = []
            for voice_name in sorted(selections):
                selections_ = selections[voice_name]
                selections_ = sequence(selections_).flatten(depth=-1)
                selections_ = copy.deepcopy(selections_)
                voice = Voice(selections_, name=voice_name)
                if attach_lilypond_voice_commands:
                    voice_name_to_command_string = {
                        "Voice_1": "voiceOne",
                        "Voice_2": "voiceTwo",
                        "Voice_3": "voiceThree",
                        "Voice_4": "voiceFour",
                    }
                    command_string = voice_name_to_command_string.get(voice_name)
                    if command_string:
                        command = LilyPondLiteral("\\" + command_string)
                        attach(command, voice)
                voices.append(voice)
            staff = Staff(voices, simultaneous=True)
            if divisions is None:
                duration = abjad_inspect(staff).duration()
                divisions = [duration]
        else:
            message = "must be list or dictionary of selections:"
            message += f" {selections!r}."
            raise TypeError(message)
        score.append(staff)
        assert isinstance(divisions, collections.abc.Sequence), repr(divisions)
        time_signatures = time_signatures or divisions
        context = Context(lilypond_type="GlobalContext")
        skips = []
        for time_signature in time_signatures:
            skip = Skip(1)
            skip.multiplier = time_signature
            attach(time_signature, skip, context="Score")
            skips.append(skip)
        context.extend(skips)
        score.insert(0, context)
        return lilypond_file
Exemplo n.º 26
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
Exemplo n.º 27
0
 def _move_indicators(self, recipient_component):
     for wrapper in inspect(self).wrappers():
         detach(wrapper, self)
         attach(wrapper, recipient_component)
Exemplo n.º 28
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
Exemplo n.º 29
0
    def _split_by_durations(self, durations, cyclic=False):
        from .Chord import Chord
        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(Tie)
        originally_repeat_tied = inspect(self).has_indicator(RepeatTie)
        result_selections = []
        # detach grace containers
        before_grace_container = self._before_grace_container
        if before_grace_container is not None:
            detach(before_grace_container, self)
        after_grace_container = self._after_grace_container
        if after_grace_container is not None:
            detach(after_grace_container, self)
        # do other things
        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)
            result_selections.append(selection)
        result_components = Sequence(result_selections).flatten(depth=-1)
        result_components = select(result_components)
        result_leaves = select(result_components).leaves(grace=False)
        assert all(isinstance(_, Selection) for _ in result_selections)
        assert all(isinstance(_, Component) for _ in result_components)
        assert result_leaves.are_leaves()
        # strip result leaves of all indicators
        for leaf in result_leaves:
            detach(object, leaf)
        # replace leaf with flattened result
        if inspect(self).parentage().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)
        # reattach grace containers
        if before_grace_container is not None:
            attach(before_grace_container, first_result_leaf)
        if after_grace_container is not None:
            attach(after_grace_container, last_result_leaf)
        # fuse tuplets
        if isinstance(result_components[0], Tuplet):
            mutate(result_components).fuse()
        # tie split notes
        if isinstance(self, (Note, Chord)) and 1 < len(result_leaves):
            result_leaves._attach_tie_to_leaves()
        if originally_repeat_tied and not inspect(
                result_leaves[0]).has_indicator(RepeatTie):
            attach(RepeatTie(), result_leaves[0])
        if originally_tied and not inspect(
                result_leaves[-1]).has_indicator(Tie):
            attach(Tie(), result_leaves[-1])
        assert isinstance(result_leaves, Selection)
        assert all(isinstance(_, Leaf) for _ in result_leaves)
        return result_leaves
Exemplo n.º 30
0
 def _construct_sequential_music(self, music):
     # indicator sorting could be rewritten into a single list using tuplets
     # with t[0] being 'forward' or 'backward' and t[1] being the indicator
     # as this better preserves attachment order. Not clear if we need it.
     container = core.Container()
     previous_leaf = None
     apply_forward = []
     apply_backward = []
     # sort events into forward or backwards attaching
     # and attach them to the proper leaf
     for x in music:
         if isinstance(x, core.Component) and not isinstance(
             x, core.BeforeGraceContainer
         ):
             for indicator in apply_forward:
                 attach(indicator, x)
             if previous_leaf:
                 for indicator in apply_backward:
                     attach(indicator, previous_leaf)
             else:
                 for indicator in apply_backward:
                     attach(indicator, x)
             apply_forward[:] = []
             apply_backward[:] = []
             previous_leaf = x
             container.append(x)
         else:
             if isinstance(x, (abjad_indicators.BarLine,)):
                 apply_backward.append(x)
             elif isinstance(x, abjad_indicators.LilyPondLiteral) and x.argument in (
                 r"\break",
                 r"\breathe",
                 r"\pageBreak",
             ):
                 apply_backward.append(x)
             else:
                 apply_forward.append(x)
     # attach remaining events to last leaf
     # or to the container itself if there were no leaves
     if previous_leaf:
         for indicator in apply_forward:
             attach(indicator, previous_leaf)
         for indicator in apply_backward:
             attach(indicator, previous_leaf)
     else:
         for indicator in apply_forward:
             attach(indicator, container)
         for indicator in apply_backward:
             attach(indicator, container)
     return container
Exemplo n.º 31
0
 def _move_indicators(self, recipient_component):
     for wrapper in inspect(self).wrappers():
         detach(wrapper, self)
         attach(wrapper, recipient_component)
Exemplo n.º 32
0
def text_spanner(
    argument: typing.Union[Component, Selection],
    *,
    selector: typings.Selector = 'abjad.select().leaves()',
    start_text_span: StartTextSpan = None,
    stop_text_span: StopTextSpan = None,
) -> None:
    r"""
    Attaches text span indicators.

    ..  container:: example

        Single spanner:

        >>> staff = abjad.Staff("c'4 d' e' f'")
        >>> start_text_span = abjad.StartTextSpan(
        ...     left_text=abjad.Markup('pont.').upright(),
        ...     right_text=abjad.Markup('tasto').upright(),
        ...     style='solid_line_with_arrow',
        ...     )
        >>> abjad.text_spanner(staff[:], start_text_span=start_text_span)
        >>> abjad.override(staff[0]).text_spanner.staff_padding = 4
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \once \override TextSpanner.staff-padding = #4
                c'4
                - \abjad_solid_line_with_arrow
                - \tweak bound-details.left.text \markup {
                    \concat
                        {
                            \upright
                                pont.
                            \hspace
                                #0.5
                        }
                    }
                - \tweak bound-details.right.text \markup {
                    \upright
                        tasto
                    }
                \startTextSpan
                d'4
                e'4
                f'4
                \stopTextSpan
            }

    ..  container:: example

        Enchained spanners:

        >>> staff = abjad.Staff("c'4 d' e' f' r")
        >>> start_text_span = abjad.StartTextSpan(
        ...     left_text=abjad.Markup('pont.').upright(),
        ...     style='dashed_line_with_arrow',
        ...     )
        >>> abjad.text_spanner(staff[:3], start_text_span=start_text_span)
        >>> start_text_span = abjad.StartTextSpan(
        ...     left_text=abjad.Markup('tasto').upright(),
        ...     right_text=abjad.Markup('pont.').upright(),
        ...     style='dashed_line_with_arrow',
        ...     )
        >>> abjad.text_spanner(staff[-3:], start_text_span=start_text_span)
        >>> abjad.override(staff).text_spanner.staff_padding = 4
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            \with
            {
                \override TextSpanner.staff-padding = #4
            }
            {
                c'4
                - \abjad_dashed_line_with_arrow
                - \tweak bound-details.left.text \markup {
                    \concat
                        {
                            \upright
                                pont.
                            \hspace
                                #0.5
                        }
                    }
                \startTextSpan
                d'4
                e'4
                \stopTextSpan
                - \abjad_dashed_line_with_arrow
                - \tweak bound-details.left.text \markup {
                    \concat
                        {
                            \upright
                                tasto
                            \hspace
                                #0.5
                        }
                    }
                - \tweak bound-details.right.text \markup {
                    \upright
                        pont.
                    }
                \startTextSpan
                f'4
                r4
                \stopTextSpan
            }

        >>> staff = abjad.Staff("c'4 d' e' f' r")
        >>> start_text_span = abjad.StartTextSpan(
        ...     left_text=abjad.Markup('pont.').upright(),
        ...     style='dashed_line_with_arrow',
        ...     )
        >>> abjad.text_spanner(staff[:3], start_text_span=start_text_span)
        >>> start_text_span = abjad.StartTextSpan(
        ...     left_text=abjad.Markup('tasto').upright(),
        ...     style='solid_line_with_hook',
        ...     )
        >>> abjad.text_spanner(staff[-3:], start_text_span=start_text_span)
        >>> abjad.override(staff).text_spanner.staff_padding = 4
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            \with
            {
                \override TextSpanner.staff-padding = #4
            }
            {
                c'4
                - \abjad_dashed_line_with_arrow
                - \tweak bound-details.left.text \markup {
                    \concat
                        {
                            \upright
                                pont.
                            \hspace
                                #0.5
                        }
                    }
                \startTextSpan
                d'4
                e'4
                \stopTextSpan
                - \abjad_solid_line_with_hook
                - \tweak bound-details.left.text \markup {
                    \concat
                        {
                            \upright
                                tasto
                            \hspace
                                #0.5
                        }
                    }
                \startTextSpan
                f'4
                r4
                \stopTextSpan
            }

    """
    import abjad
    start_text_span = start_text_span or StartTextSpan()
    stop_text_span = stop_text_span or StopTextSpan()

    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]

    attach(start_text_span, start_leaf)
    attach(stop_text_span, stop_leaf)