Source code for auxjad.mutate.extract_trivial_tuplets
import abjad
[docs]def extract_trivial_tuplets(selection: abjad.Selection) -> None:
r"""Mutates an input |abjad.Selection| in place and has no return value;
this function looks for tuplets filled with rests or with tied notes or
chords and replaces them with a single leaf.
Basic usage:
Usage is simple:
>>> staff = abjad.Staff(
... r"\times 2/3 {r4 r2} \times 2/3 {c'8 ~ c'8 ~ c'2}"
... )
>>> abjad.show(container)
.. docs::
{
\times 2/3
{
r4
r2
}
\times 2/3
{
c'8
~
c'8
~
c'2
}
}
.. figure:: ../_images/extract_trivial_tuplets-4htz2xebxwf.png
>>> auxjad.mutate(container[:]).extract_trivial_tuplets()
>>> abjad.show(container)
.. docs::
{
r2
c'2
}
.. figure:: ../_images/extract_trivial_tuplets-2dbuwo4erhb.png
It also works with containers with tuplets within tuplets.
>>> container = abjad.Container(r"\times 4/5 {r2. \times 2/3 {r2 r4}}")
>>> abjad.show(container)
.. docs::
{
\times 4/5
{
r2.
\times 2/3
{
r2
r4
}
}
}
.. figure:: ../_images/extract_trivial_tuplets-8d5bcyxcmhc.png
>>> auxjad.mutate(container[:]).extract_trivial_tuplets()
>>> abjad.show(container)
.. docs::
{
r1
}
.. figure:: ../_images/extract_trivial_tuplets-2a2fvwimyrx.png
>>> container = abjad.Container(
... r"\times 4/5 {c'2. ~ \times 2/3 {c'2 ~ c'4}}"
... )
>>> abjad.show(container)
.. docs::
{
\times 4/5
{
c'2.
~
\times 2/3
{
c'2
~
c'4
}
}
}
.. figure:: ../_images/extract_trivial_tuplets-xka6r5iyo4l.png
>>> auxjad.mutate(staff[:]).extract_trivial_tuplets()
>>> abjad.show(container)
.. docs::
{
c'1
}
.. figure:: ../_images/extract_trivial_tuplets-f1qxi44xcsw.png
.. note::
Auxjad automatically adds this function as an extension function to
|abjad.mutate|. It can thus be used from either |auxjad.mutate|_ or
|abjad.mutate| namespaces. Therefore, the two lines below are
equivalent:
>>> auxjad.mutate(staff[:]).extract_trivial_tuplets()
>>> abjad.mutate(staff[:]).extract_trivial_tuplets()
Partial extraction:
This function also extracts tuplets within tuplets.
>>> container = abjad.Container(
... r"r2 \times 2/3 {r2 r4} \times 4/5 {c'2. \times 2/3 {r2 r4}}"
... )
>>> abjad.show(container)
.. docs::
{
r2
\times 2/3
{
r2
r4
}
\times 4/5
{
c'2.
\times 2/3
{
r2
r4
}
}
}
.. figure:: ../_images/extract_trivial_tuplets-adibnkb1mbs.png
>>> auxjad.mutate(container[:]).extract_trivial_tuplets()
>>> abjad.show(container)
.. docs::
{
r2
r2
\times 4/5
{
c'2.
r2
}
}
.. figure:: ../_images/extract_trivial_tuplets-xldohyedqs.png
.. tip::
Use |auxjad.mutate.rests_to_multimeasure_rest()| to replace measures
filled with rests by a single multi-measure rest. That function makes
use of |auxjad.mutate.extract_trivial_tuplets()|, so it is not
necessary to flatten the empty tuplets beforehand.
Time signature changes:
Works with measures with any time signature.
>>> container = abjad.Staff(r"\time 3/4 r2. \times 3/2 {r4 r4}")
>>> auxjad.mutate(container[:]).extract_trivial_tuplets()
>>> abjad.show(container)
.. docs::
\new Staff
{
\time 3/4
r2.
r2.
}
.. figure:: ../_images/extract_trivial_tuplets-sa1tqmvtkx.png
Non-assignable durations:
This function also extracts tuplets which sum up to a non-assignable
duration. In this case, it creates multiple leaves and substitutes them
for the original tuplet. Indicators are passed on to the first leaf of
the new leaves.
>>> staff = abjad.Staff(r"\time 6/4 c'4\f \times 5/6 {g1.\p}")
>>> abjad.show(staff)
.. docs::
\new Staff
{
\time 6/4
c'4
\f
\tweak text #tuplet-number::calc-fraction-text
\times 5/6
{
g1.
\p
}
}
.. figure:: ../_images/extract_trivial_tuplets-l4kp9g5v7m.png
>>> abjad.mutate(staff[:]).extract_trivial_tuplets()
>>> abjad.show(staff)
.. docs::
\new Staff
{
\time 6/4
c'4
\f
g1
\p
~
g4
}
.. figure:: ../_images/extract_trivial_tuplets-8r40ndemvpn.png
.. note::
When using |abjad.Container|'s, all time signatures in the output will
be commented out with ``%%%.`` This is because Abjad only applies time
signatures to containers that belong to a |abjad.Staff|. The present
function works with either |abjad.Container| and |abjad.Staff|.
>>> container = abjad.Container(r"\time 3/4 c'4 d'4 e'4")
>>> abjad.show(container)
.. docs::
{
%%% \time 3/4 %%%
c'4
d'4
e'4
}
.. figure:: ../_images/extract_trivial_tuplets-6wymsb7z1n4.png
>>> staff = abjad.Staff([container])
>>> abjad.show(container)
.. docs::
{
\time 3/4
c'4
d'4
e'4
}
.. figure:: ../_images/extract_trivial_tuplets-moavfyqtxza.png
.. warning::
The input selection must be a contiguous logical voice. When dealing
with a container with multiple subcontainers (e.g. a score containing
multiple staves), the best approach is to cycle through these
subcontainers, applying this function to them individually.
"""
if not isinstance(selection, abjad.Selection):
raise TypeError("argument must be 'abjad.Selection'")
tuplets = selection.tuplets()
if len(tuplets) == 0:
return
for tuplet in tuplets:
leaves = abjad.select(tuplet).leaves()
if (all(isinstance(leaf, abjad.Rest) for leaf in leaves)
and len(leaves) > 1):
duration = tuplet.multiplied_duration
rests = abjad.LeafMaker()(None, duration)
time_signature = abjad.get.indicator(
leaves[0],
abjad.TimeSignature,
)
if time_signature is not None:
abjad.attach(time_signature, rests[0])
abjad.mutate.replace(tuplet, rests)
if abjad.get.sustained(tuplet):
duration = tuplet.multiplied_duration
n_elements = len(tuplet)
after_tie = abjad.get.indicator(leaves[-1], abjad.Tie)
for _ in range(n_elements - 1):
tuplet.pop(-1)
if not after_tie:
abjad.detach(abjad.Tie, leaves[0])
if duration.is_assignable:
leaves[0].written_duration = duration
abjad.mutate.extract(tuplet)
elif duration.implied_prolation == 1:
if isinstance(leaves[0], abjad.Note):
pitch = leaves[0].written_pitch
elif isinstance(leaves[0], abjad.Chord):
pitch = leaves[0].written_pitches
else:
pitch = None
notes = abjad.LeafMaker()(pitch, duration)
indicators = abjad.get.indicators(leaves[0])
for indicator in indicators:
abjad.attach(indicator, notes[0])
abjad.mutate.replace(leaves[0], notes)
abjad.mutate.extract(tuplet)
else:
continue
for tuplet in tuplets:
if tuplet.trivializable():
tuplet.trivialize()
abjad.mutate.extract(tuplet)