Source code for auxjad.select.logical_selections

from typing import Union

import abjad


def _group_consecutive_rests(logical_tie: abjad.LogicalTie,
                             ) -> Union[abjad.Leaf, bool]:
    r"""Private function used by |auxjad.select.logical_selections()| in order
    to group consecutive ties together. If a logical tie is made out of a rest,
    this function returns the value ``True``, otherwise it returns the logical
    tie's head object itself. When this output is used with
    |abjad.select.group_by()|, consecutive ``True`` values will be grouped
    together, thus selecting consecutive rests as a single 'logical selection'.
    Meanwhile, non-rest logical ties will return their individual unique head
    object, maintaining their individual selections as is.
    """
    if isinstance(logical_tie.head, (abjad.Rest, abjad.MultimeasureRest)):
        return True
    else:
        return logical_tie.head


[docs]def logical_selections(container: Union[abjad.Container, abjad.Selection], ) -> abjad.Selection: r"""Takes an |abjad.Container| (or child class). Returns the logical selections of a container, that is the logical ties but with consecutive rests grouped together. Return value is in the form of a |abjad.Selection| of |abjad.Selection|'s. Basic usage: Usage is similar to |abjad.select.logical_ties()|: >>> container = abjad.Container(r"c'4 ~ c'16 r8. r4.. d'16 ~ d'4") >>> logical_selections = auxjad.select.logical_selections(container) >>> for logical_selection in logical_selections: ... print(logical_selection.leaves()) Selection([Note("c'4"), Note("c'16")]) Selection([Rest('r8.'), Rest('r4..')]) Selection([Note("d'16"), Note("d'4")]) .. note:: Auxjad automatically adds this function as an extension function to |abjad.select|. It can thus be used from either |auxjad.select|_ or |abjad.select| namespaces. Therefore, the two lines below are equivalent: >>> container = abjad.Container(r"c'4 ~ c'16 r8. r4.. d'16 ~ d'4") >>> for logical_sel in auxjad.select.logical_selections(container): ... print(logical_sel.leaves()) Selection([Note("c'4"), Note("c'16")]) Selection([Rest('r8.'), Rest('r4..')]) Selection([Note("d'16"), Note("d'4")]) >>> for logical_sel in abjad.select.logical_selections(container): ... print(logical_sel.leaves()) Selection([Note("c'4"), Note("c'16")]) Selection([Rest('r8.'), Rest('r4..')]) Selection([Note("d'16"), Note("d'4")]) Multi-measure rests: It also handles multi-measure rests. >>> container = abjad.Container(r"c'2. ~ c'16 r8. R1 r4.. d'16 ~ d'2.") >>> logical_selections = auxjad.select.logical_selections(container) >>> for logical_selection in logical_selections: ... print(logical_selection.leaves()) Selection([Note("c'2."), Note("c'16")]) Selection([Rest('r8.'), MultimeasureRest('R1'), Rest('r4..')]) Selection([Note("d'16"), Note("d'2.")]) """ if not isinstance(container, (abjad.Container, abjad.Selection)): raise TypeError("Argument must be 'abjad.Container', 'abjad.Selection'" ", or child classes") if isinstance(container, abjad.Container): if not abjad.select(container).leaves().are_contiguous_logical_voice(): raise ValueError("Argument must be contiguous logical voice") logical_ties = abjad.select(container).logical_ties() return logical_ties.group_by(_group_consecutive_rests)