detach

abjad.top.detach.detach(argument, target=None, by_id=False)

Detaches indicators-equal-to-argument from target.

When target is none argument must be a spanner; spanner will then detach from all leaves to which spanner attaches.

Set by_id to true to detach exact argument from target (rather than detaching all indicators-equal-to-argument).

Detaches articulations from first note in staff:

>>> staff = abjad.Staff("c'4 d' e' f'")
>>> abjad.attach(abjad.Articulation('>'), staff[0])
>>> abjad.show(staff) 
>>> abjad.detach(abjad.Articulation, staff[0])
(Articulation('>'),)
>>> abjad.show(staff) 

The use of by_id is motivated by the following.

Consider the three document-specifier markups below:

>>> markup_1 = abjad.Markup('tutti', direction=abjad.Up)
>>> markup_2 = abjad.Markup('with the others', direction=abjad.Up)
>>> markup_3 = abjad.Markup('with the others', direction=abjad.Up)

Markups two and three compare equal:

>>> markup_2 == markup_3
True

But document-tagging like this makes sense for score and two diferent parts:

>>> staff = abjad.Staff("c'4 d' e' f'")
>>> abjad.attach(markup_1, staff[0], tag='+SCORE')
>>> abjad.attach(
...     markup_2,
...     staff[0],
...     deactivate=True,
...     tag='+PARTS_VIOLIN_1',
...     )
>>> abjad.attach(
...     markup_3,
...     staff[0],
...     deactivate=True,
...     tag='+PARTS_VIOLIN_2',
...     )
>>> abjad.show(staff) 
>>> abjad.f(staff, strict=50)
\new Staff
{
    c'4
    ^ \markup { tutti }                           %! +SCORE
%@% ^ \markup { "with the others" }               %! +PARTS_VIOLIN_1
%@% ^ \markup { "with the others" }               %! +PARTS_VIOLIN_2
    d'4
    e'4
    f'4
}

The question is then how to detach just one of the two markups that compare equal to each other?

Passing in one of the markup objects directory doesn’t work. This is because detach tests for equality to input argument:

>>> abjad.detach(markup_2, staff[0])
(Markup(contents=['with the others'], direction=Up), Markup(contents=['with the others'], direction=Up))
>>> abjad.show(staff) 
>>> abjad.f(staff, strict=50)
\new Staff
{
    c'4
    ^ \markup { tutti }                           %! +SCORE
    d'4
    e'4
    f'4
}

We start again:

>>> staff = abjad.Staff("c'4 d' e' f'")
>>> abjad.attach(markup_1, staff[0], tag='+SCORE')
>>> abjad.attach(
...     markup_2,
...     staff[0],
...     deactivate=True,
...     tag='+PARTS_VIOLIN_1',
...     )
>>> abjad.attach(
...     markup_3,
...     staff[0],
...     deactivate=True,
...     tag='+PARTS_VIOLIN_2',
...     )
>>> abjad.show(staff) 
>>> abjad.f(staff, strict=50)
\new Staff
{
    c'4
    ^ \markup { tutti }                           %! +SCORE
%@% ^ \markup { "with the others" }               %! +PARTS_VIOLIN_1
%@% ^ \markup { "with the others" }               %! +PARTS_VIOLIN_2
    d'4
    e'4
    f'4
}

This time we set by_id to true. Now detach checks the exact id of its input argument (rather than just testing for equality). This gives us what we want:

>>> abjad.detach(markup_2, staff[0], by_id=True)
(Markup(contents=['with the others'], direction=Up),)
>>> abjad.show(staff) 
>>> abjad.f(staff, strict=50)
\new Staff
{
    c'4
    ^ \markup { tutti }                           %! +SCORE
%@% ^ \markup { "with the others" }               %! +PARTS_VIOLIN_2
    d'4
    e'4
    f'4
}

REGRESSION. Attach-detach-attach pattern works correctly when detaching wrappers:

>>> staff = abjad.Staff("c'4 d' e' f'")
>>> abjad.attach(abjad.Clef('alto'), staff[0])
>>> abjad.show(staff) 
>>> wrapper = abjad.inspect(staff[0]).wrappers()[0]
>>> abjad.detach(wrapper, wrapper.component)
(Wrapper(context='Staff', indicator=Clef('alto'), tag=Tag()),)
>>> abjad.show(staff) 
>>> abjad.attach(abjad.Clef('tenor'), staff[0])
>>> abjad.show(staff) 

Returns tuple of zero or more detached items.