spanners
Classes and functions for modeling spanners: beams, hairpins, slurs, etc.
Functions
Attaches beam indicators. |
|
Attaches glissando indicators. |
|
Attaches hairpin indicators. |
|
Attaches group indicators. |
|
Attaches ottava indicators. |
|
Attaches phrasing slur indicators. |
|
Attaches piano pedal indicators. |
|
Attaches slur indicators. |
|
Attaches text span indicators. |
|
Attaches tie indicators. |
|
Attaches trill spanner indicators. |
- abjad.spanners.beam(argument: Component | Sequence[Component], *, beam_lone_notes: bool = False, beam_rests: bool | None = True, direction: Vertical | None = None, durations: Sequence[Duration] | None = None, span_beam_count: int | None = None, start_beam: StartBeam | Bundle | None = None, stemlet_length: int | float | None = None, stop_beam: StopBeam | None = None, tag: Tag | None = None) None [source]
Attaches beam indicators.
>>> voice = abjad.Voice("c'8 d' e' f'") >>> abjad.beam(voice[:], direction=abjad.UP) >>> abjad.show(voice)
Does not beam rests:
>>> voice = abjad.Voice("c'8 r e' f'") >>> abjad.beam(voice[:], beam_rests=False) >>> abjad.show(voice)
Does beam rests:
>>> voice = abjad.Voice("c'8 r e' f'") >>> abjad.beam(voice[:], beam_rests=True) >>> abjad.show(voice)
Beams rests and sets stemlet length:
>>> voice = abjad.Voice("c'8 r e' f'") >>> abjad.beam(voice[:], beam_rests=True, stemlet_length=1) >>> abjad.show(voice)
- abjad.spanners.glissando(argument, *tweaks, allow_repeats: bool = False, allow_ties: bool = False, hide_middle_note_heads: bool = False, hide_middle_stems: bool = False, left_broken: bool = False, parenthesize_repeats: bool = False, right_broken: bool = False, right_broken_show_next: bool = False, tag: Tag | None = None, zero_padding: bool = False)[source]
Attaches glissando indicators.
>>> voice = abjad.Voice("c'8 d'8 e'8 f'8", name="Voice") >>> staff = abjad.Staff([voice], name="Staff") >>> abjad.glissando(voice[:]) >>> abjad.show(staff)
Glissando avoids bend-after indicators:
>>> voice = abjad.Voice("c'8 d'8 e'8 f'8", name="Voice") >>> staff = abjad.Staff([voice], name="Staff") >>> bend_after = abjad.BendAfter() >>> abjad.attach(bend_after, voice[1]) >>> abjad.glissando(voice[:]) >>> abjad.show(staff)
Does not allow repeated pitches:
>>> voice = abjad.Voice("a8 a8 b8 ~ b8 c'8 c'8 d'8 ~ d'8", name="Voice") >>> staff = abjad.Staff([voice], name="Staff") >>> abjad.glissando(voice[:], allow_repeats=True) >>> abjad.show(staff)
Allows repeated pitches (but not ties):
>>> voice = abjad.Voice("a8 a8 b8 ~ b8 c'8 c'8 d'8 ~ d'8", name="Voice") >>> staff = abjad.Staff([voice], name="Staff") >>> abjad.glissando(voice[:], allow_repeats=True) >>> abjad.show(staff)
Allows both repeated pitches and ties:
>>> voice = abjad.Voice("a8 a8 b8 ~ b8 c'8 c'8 d'8 ~ d'8", name="Voice") >>> staff = abjad.Staff([voice], name="Staff") >>> abjad.glissando( ... voice[:], ... allow_repeats=True, ... allow_ties=True, ... ) >>> abjad.show(staff)
Ties are excluded when repeated pitches are not allowed because all ties comprise repeated pitches.
Spans and parenthesizes repeated pitches:
>>> voice = abjad.Voice("a8 a8 b8 ~ b8 c'8 c'8 d'8 ~ d'8", name="Voice") >>> staff = abjad.Staff([voice], name="Staff") >>> abjad.glissando( ... voice[:], ... allow_repeats=True, ... parenthesize_repeats=True, ... ) >>> abjad.show(staff)
Parenthesizes (but does not span) repeated pitches:
>>> voice = abjad.Voice("a8 a8 b8 ~ b8 c'8 c'8 d'8 ~ d'8", name="Voice") >>> staff = abjad.Staff([voice], name="Staff") >>> abjad.glissando( ... voice[:], ... parenthesize_repeats=True, ... ) >>> abjad.show(staff)
With
hide_middle_note_heads=True
:>>> voice = abjad.Voice("c'8 d'8 e'8 f'8", name="Voice") >>> staff = abjad.Staff([voice], name="Staff") >>> abjad.glissando(voice[:], hide_middle_note_heads=True) >>> abjad.show(staff)
With
hide_middle_note_heads=True
andhide_middle_stems=True
:>>> voice = abjad.Voice("c'8 d'8 e'8 f'8", name="Voice") >>> abjad.glissando( ... voice[:], ... hide_middle_note_heads=True, ... hide_middle_stems=True, ... ) >>> abjad.show(voice)
Note
Respects
hide_middle_stems
only whenhide_middle_note_heads=True
.With
right_broken=True
:>>> voice = abjad.Voice("c'8 d'8 e'8 f'8", name="Voice") >>> abjad.glissando(voice[:], right_broken=True) >>> abjad.show(voice)
LilyPond output looks like this:
>>> string = abjad.lilypond(voice, tags=True) >>> print(string) \context Voice = "Voice" { c'8 %! abjad.glissando(7) \glissando d'8 %! abjad.glissando(7) \glissando e'8 %! abjad.glissando(7) \glissando f'8 %! SHOW_TO_JOIN_BROKEN_SPANNERS %! abjad.glissando(7) %@% \glissando }
With
right_broken=True
andhide_middle_note_heads=True
:>>> voice = abjad.Voice("c'8 d'8 e'8 f'8", name="Voice") >>> abjad.glissando( ... voice[:], ... right_broken=True, ... hide_middle_note_heads=True, ... ) >>> abjad.show(voice)
LilyPond output looks like this:
>>> string = abjad.lilypond(voice, tags=True) >>> print(string) \context Voice = "Voice" { c'8 %! abjad.glissando(7) \glissando %! RIGHT_BROKEN %! SHOW_TO_JOIN_BROKEN_SPANNERS %! abjad.glissando(0) \hide NoteHead %! RIGHT_BROKEN %! SHOW_TO_JOIN_BROKEN_SPANNERS %! abjad.glissando(0) \override Accidental.stencil = ##f %! RIGHT_BROKEN %! SHOW_TO_JOIN_BROKEN_SPANNERS %! abjad.glissando(0) \override NoteColumn.glissando-skip = ##t %! RIGHT_BROKEN %! SHOW_TO_JOIN_BROKEN_SPANNERS %! abjad.glissando(0) \override NoteHead.no-ledgers = ##t d'8 e'8 %! HIDE_TO_JOIN_BROKEN_SPANNERS %! RIGHT_BROKEN %! abjad.glissando(4) \revert Accidental.stencil %! HIDE_TO_JOIN_BROKEN_SPANNERS %! RIGHT_BROKEN %! abjad.glissando(4) \revert NoteColumn.glissando-skip %! HIDE_TO_JOIN_BROKEN_SPANNERS %! RIGHT_BROKEN %! abjad.glissando(4) \revert NoteHead.no-ledgers %! HIDE_TO_JOIN_BROKEN_SPANNERS %! RIGHT_BROKEN %! abjad.glissando(4) \undo \hide NoteHead f'8 }
With
right_broken=True
,hide_middle_note_heads=True
andright_broken_show_next=True
:>>> voice = abjad.Voice("c'8 d'8 e'8 f'8", name="Voice") >>> abjad.glissando( ... voice[:], ... hide_middle_note_heads=True, ... right_broken=True, ... right_broken_show_next=True, ... ) >>> abjad.show(voice)
LilyPond output looks like this:
>>> string = abjad.lilypond(voice, tags=True) >>> print(string) \context Voice = "Voice" { c'8 %! abjad.glissando(7) \glissando %! RIGHT_BROKEN %! SHOW_TO_JOIN_BROKEN_SPANNERS %! abjad.glissando(0) \hide NoteHead %! RIGHT_BROKEN %! SHOW_TO_JOIN_BROKEN_SPANNERS %! abjad.glissando(0) \override Accidental.stencil = ##f %! RIGHT_BROKEN %! SHOW_TO_JOIN_BROKEN_SPANNERS %! abjad.glissando(0) \override NoteColumn.glissando-skip = ##t %! RIGHT_BROKEN %! SHOW_TO_JOIN_BROKEN_SPANNERS %! abjad.glissando(0) \override NoteHead.no-ledgers = ##t d'8 e'8 %! HIDE_TO_JOIN_BROKEN_SPANNERS %! RIGHT_BROKEN %! abjad.glissando(4) \revert Accidental.stencil %! HIDE_TO_JOIN_BROKEN_SPANNERS %! RIGHT_BROKEN %! abjad.glissando(4) \revert NoteColumn.glissando-skip %! HIDE_TO_JOIN_BROKEN_SPANNERS %! RIGHT_BROKEN %! abjad.glissando(4) \revert NoteHead.no-ledgers %! HIDE_TO_JOIN_BROKEN_SPANNERS %! RIGHT_BROKEN %! abjad.glissando(4) \undo \hide NoteHead f'8 %! RIGHT_BROKEN_SHOW_NEXT %! SHOW_TO_JOIN_BROKEN_SPANNERS %! abjad.glissando(5) %@% \revert Accidental.stencil %! RIGHT_BROKEN_SHOW_NEXT %! SHOW_TO_JOIN_BROKEN_SPANNERS %! abjad.glissando(5) %@% \revert NoteColumn.glissando-skip %! RIGHT_BROKEN_SHOW_NEXT %! SHOW_TO_JOIN_BROKEN_SPANNERS %! abjad.glissando(5) %@% \revert NoteHead.no-ledgers %! RIGHT_BROKEN_SHOW_NEXT %! SHOW_TO_JOIN_BROKEN_SPANNERS %! abjad.glissando(5) %@% \undo \hide NoteHead }
With
left_broken=True
(andhide_middle_note_heads=True
):>>> voice = abjad.Voice("c'8 d'8 e'8 f'8", name="Voice") >>> abjad.glissando( ... voice[:], ... left_broken=True, ... hide_middle_note_heads=True, ... ) >>> abjad.show(voice)
LilyPond output looks like this:
>>> string = abjad.lilypond(voice, tags=True) >>> print(string) \context Voice = "Voice" { %! HIDE_TO_JOIN_BROKEN_SPANNERS %! LEFT_BROKEN %! abjad.glissando(2) \hide NoteHead %! HIDE_TO_JOIN_BROKEN_SPANNERS %! LEFT_BROKEN %! abjad.glissando(2) \override Accidental.stencil = ##f %! HIDE_TO_JOIN_BROKEN_SPANNERS %! LEFT_BROKEN %! abjad.glissando(2) \override NoteHead.no-ledgers = ##t c'8 %! abjad.glissando(7) \glissando %! HIDE_TO_JOIN_BROKEN_SPANNERS %! LEFT_BROKEN %! abjad.glissando(3) \override NoteColumn.glissando-skip = ##t d'8 e'8 %! abjad.glissando(6) \revert Accidental.stencil %! abjad.glissando(6) \revert NoteColumn.glissando-skip %! abjad.glissando(6) \revert NoteHead.no-ledgers %! abjad.glissando(6) \undo \hide NoteHead f'8 }
Note
Respects left-broken only with
hide_middle_note_heads=True
.Tweaks apply to every glissando:
>>> voice = abjad.Voice("c'8 d'8 e'8 f'8", name="Voice") >>> abjad.glissando( ... voice[:], ... abjad.Tweak(r"- \tweak style #'trill"), ... ) >>> abjad.show(voice)
With
zero_padding=True
on fixed pitch:>>> voice = abjad.Voice("d'8 d'4. d'4. d'8", name="Voice")
>>> abjad.glissando( ... voice[:], ... allow_repeats=True, ... zero_padding=True, ... ) >>> for note in voice[1:]: ... abjad.override(note).NoteHead.transparent = True ... abjad.override(note).NoteHead.X_extent = "#'(0 . 0)" ... >>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', voice]) >>> abjad.show(lilypond_file)
With
zero_padding=True
on changing pitches:>>> voice = abjad.Voice("c'8. d'8. e'8. f'8.", name="Voice") >>> abjad.glissando(voice[:], zero_padding=True) >>> for note in voice[1:-1]: ... abjad.override(note).NoteHead.transparent = True ... abjad.override(note).NoteHead.X_extent = "#'(0 . 0)" ... >>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', voice]) >>> abjad.show(lilypond_file)
With indexed tweaks:
>>> voice = abjad.Voice("d'4 d' d' d'", name="Voice") >>> abjad.glissando( ... voice[:], ... abjad.Tweak(r"- \tweak color #red", i=0), ... abjad.Tweak(r"- \tweak color #red", i=-1), ... allow_repeats=True, ... zero_padding=True, ... ) >>> for note in voice[1:-1]: ... abjad.override(note).NoteHead.transparent = True ... abjad.override(note).NoteHead.X_extent = "#'(0 . 0)" ... >>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', voice]) >>> abjad.show(lilypond_file)
- abjad.spanners.hairpin(descriptor: str, argument: Component | Sequence[Component], *, direction: Vertical | None = None, tag: Tag | None = None) None [source]
Attaches hairpin indicators.
With three-part string descriptor:
>>> voice = abjad.Voice("c'4 d' e' f'") >>> abjad.hairpin("p < f", voice[:], direction=abjad.UP) >>> abjad.override(voice[0]).DynamicLineSpanner.staff_padding = 4 >>> abjad.show(voice)
With two-part string descriptor:
>>> voice = abjad.Voice("c'4 d' e' f'") >>> abjad.hairpin("< !", voice[:]) >>> abjad.override(voice[0]).DynamicLineSpanner.staff_padding = 4 >>> abjad.show(voice)
With dynamic objects:
>>> voice = abjad.Voice("c'4 d' e' f'") >>> start_hairpin = abjad.StartHairpin("o<|") >>> bundle = abjad.bundle(start_hairpin, r"- \tweak color #blue") >>> stop_dynamic = abjad.Dynamic('"f"') >>> abjad.hairpin([bundle, stop_dynamic], voice[:]) >>> abjad.override(voice[0]).DynamicLineSpanner.staff_padding = 4 >>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', voice]) >>> abjad.show(lilypond_file)
- abjad.spanners.horizontal_bracket(argument: Component | Sequence[Component], *, start_group: StartGroup | Bundle | None = None, stop_group: StopGroup | None = None, tag: Tag | None = None) None [source]
Attaches group indicators.
>>> voice = abjad.Voice("c'4 d' e' f'") >>> voice.consists_commands.append("Horizontal_bracket_engraver") >>> abjad.horizontal_bracket(voice[:]) >>> abjad.show(voice)
Bundle start-group indicators to tweak the padding and outside-staff priority of nested analysis brackets:
>>> voice = abjad.Voice("c'4 d' e' f' c' d' e' f'") >>> voice.consists_commands.append("Horizontal_bracket_engraver") >>> bundle = abjad.bundle( ... abjad.StartGroup(), ... r"- \tweak color #red", ... r"- \tweak padding 1.5", ... comment="% lexical order 1", ... ) >>> abjad.horizontal_bracket(voice[:4], start_group=bundle) >>> bundle = abjad.bundle( ... abjad.StartGroup(), ... r"- \tweak color #red", ... r"- \tweak padding 1.5", ... comment="% lexical order 1", ... ) >>> abjad.horizontal_bracket(voice[4:], start_group=bundle) >>> bundle = abjad.bundle( ... abjad.StartGroup(), ... r"- \tweak color #blue", ... r"- \tweak outside-staff-priority 801", ... r"- \tweak padding 1.5", ... comment="% lexical order 0", ... ) >>> abjad.horizontal_bracket(voice[:], start_group=bundle)
>>> abjad.show(voice)
- abjad.spanners.ottava(argument: Component | Sequence[Component], *, start_ottava: Ottava = Ottava(n=1, site='before'), stop_ottava: Ottava = Ottava(n=0, site='after'), tag: Tag | None = None) None [source]
Attaches ottava indicators.
>>> staff = abjad.Staff("c'4 d' e' f'") >>> abjad.ottava(staff[:]) >>> abjad.show(staff)
- abjad.spanners.phrasing_slur(argument: Component | Sequence[Component], *, direction: Vertical | None = None, start_phrasing_slur: StartPhrasingSlur | Bundle | None = None, stop_phrasing_slur: StopPhrasingSlur | None = None, tag: Tag | None = None) None [source]
Attaches phrasing slur indicators.
>>> voice = abjad.Voice("c'4 d' e' f'") >>> abjad.phrasing_slur(voice[:], direction=abjad.UP) >>> abjad.show(voice)
- abjad.spanners.piano_pedal(argument: Component | Sequence[Component], *, context: str | None = None, start_piano_pedal: StartPianoPedal | Bundle | None = None, stop_piano_pedal: StopPianoPedal | None = None, tag: Tag | None = None) None [source]
Attaches piano pedal indicators.
>>> staff = abjad.Staff("c'4 d' e' f'") >>> abjad.piano_pedal(staff[:], context="Staff") >>> abjad.setting(staff).pedalSustainStyle = "#'mixed" >>> abjad.override(staff).SustainPedalLineSpanner.staff_padding = 5 >>> abjad.show(staff)
- abjad.spanners.slur(argument: Component | Sequence[Component], *, direction: Vertical | None = None, start_slur: StartSlur | Bundle | None = None, stop_slur: StopSlur | None = None, tag: Tag | None = None) None [source]
Attaches slur indicators.
>>> voice = abjad.Voice("c'4 d' e' f'") >>> abjad.slur(voice[:], direction=abjad.UP) >>> abjad.show(voice)
- abjad.spanners.text_spanner(argument: Component | Sequence[Component], *, direction: Vertical | None = None, start_text_span: StartTextSpan | Bundle | None = None, stop_text_span: StopTextSpan | None = None, tag: Tag | None = None) None [source]
Attaches text span indicators.
Single spanner:
>>> voice = abjad.Voice("c'4 d' e' f'") >>> start_text_span = abjad.StartTextSpan( ... left_text=abjad.Markup(r"\upright pont."), ... right_text=abjad.Markup(r"\markup \upright tasto"), ... style=r"\abjad-solid-line-with-arrow", ... ) >>> abjad.text_spanner( ... voice[:], direction=abjad.UP, start_text_span=start_text_span ... ) >>> abjad.override(voice[0]).TextSpanner.staff_padding = 4 >>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', voice]) >>> abjad.show(lilypond_file)
Enchained spanners:
>>> voice = abjad.Voice("c'4 d' e' f' r") >>> start_text_span = abjad.StartTextSpan( ... left_text=abjad.Markup(r"\upright pont."), ... style=r"\abjad-dashed-line-with-arrow", ... ) >>> abjad.text_spanner(voice[:3], start_text_span=start_text_span) >>> start_text_span = abjad.StartTextSpan( ... left_text=abjad.Markup(r"\upright tasto"), ... right_text=abjad.Markup(r"\markup \upright pont."), ... style=r"\abjad-dashed-line-with-arrow", ... ) >>> abjad.text_spanner(voice[-3:], start_text_span=start_text_span) >>> abjad.override(voice).TextSpanner.staff_padding = 4 >>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', voice]) >>> abjad.show(lilypond_file)
>>> voice = abjad.Voice("c'4 d' e' f' r") >>> start_text_span = abjad.StartTextSpan( ... left_text=abjad.Markup(r"\upright pont."), ... style=r"\abjad-dashed-line-with-arrow", ... ) >>> abjad.text_spanner(voice[:3], start_text_span=start_text_span) >>> start_text_span = abjad.StartTextSpan( ... left_text=abjad.Markup(r"\upright tasto"), ... style=r"\abjad-solid-line-with-hook", ... ) >>> abjad.text_spanner(voice[-3:], start_text_span=start_text_span) >>> abjad.override(voice).TextSpanner.staff_padding = 4 >>> lilypond_file = abjad.LilyPondFile([r'\include "abjad.ily"', voice]) >>> abjad.show(lilypond_file)
- abjad.spanners.tie(argument: Component | Sequence[Component], *, direction: Vertical | None = None, repeat: bool | tuple[int, int] | Callable = False, tag: Tag | None = None) None [source]
Attaches tie indicators.
>>> staff = abjad.Staff("c'4 c' c' c'") >>> abjad.tie(staff[:], direction=abjad.UP) >>> abjad.show(staff)
With repeat ties:
>>> voice = abjad.Voice("c'4 c' c' c'", name="Voice") >>> abjad.tie(voice[:], repeat=True) >>> abjad.show(voice)
Removes any existing ties before attaching new tie:
>>> voice = abjad.Voice("c'4 ~ c' ~ c' ~ c'", name="Voice") >>> abjad.tie(voice[:]) >>> abjad.show(voice)
Ties consecutive chords if all adjacent pairs have at least one pitch in common:
>>> voice = abjad.Voice("<c'>4 <c' d'>4 <d'>4", name="Voice") >>> abjad.tie(voice[:]) >>> abjad.show(voice)
Enharmonics are allowed:
>>> voice = abjad.Voice("c'4 bs c' dff'", name="Voice") >>> abjad.tie(voice[:]) >>> abjad.show(voice)
Repeat tie threshold works like this:
>>> voice = abjad.Voice("d'4. d'2 d'4. d'2", name="Voice") >>> abjad.tie(voice[:], repeat=(4, 8)) >>> abjad.show(voice)
Detaches ties before attach:
>>> voice = abjad.Voice("d'2 ~ d'8 ~ d'8 ~ d'8 ~ d'8", name="Voice") >>> abjad.show(voice)
>>> abjad.tie(voice[:], repeat=(4, 8)) >>> abjad.show(voice)
- abjad.spanners.trill_spanner(argument: Component | Sequence[Component], *, start_trill_span: StartTrillSpan | Bundle | None = None, stop_trill_span: StopTrillSpan | None = None, tag: Tag | None = None) None [source]
Attaches trill spanner indicators.
>>> voice = abjad.Voice("c'4 d' e' f'") >>> abjad.trill_spanner(voice[:]) >>> abjad.show(voice)