In 2011, Xavier Scheuer published a code snippet allowing consecutive rehearsal marks using the multi-mark engraver. The code worked until now. In Lilypond 2.24.1 it fails. Here is an example that worked before (sorry, a lot of code):
\version "2.22.1"
\language "italiano"
#(set-global-staff-size 18)
openBracket =
\tweak self-alignment-X #'()
\tweak break-visibility #end-of-line-invisible
\mark \markup {
\path #0.2 #'((moveto 0 0) (lineto 0 2) (lineto 1.3 2))
}
closeBracket =
\tweak self-alignment-X #'()
\tweak break-visibility #begin-of-line-invisible
\mark \markup {
\path #0.2 #'((moveto 0 0) (lineto 0 2) (lineto -1.3 2))
}
doubleBracket =
\tweak self-alignment-X #'()
\tweak break-visibility #begin-of-line-invisible
\mark \markup {
\path #0.2 #'((moveto -0.2 0) (lineto -0.2 2) (lineto -1.5 2)
(moveto 0.2 0) (lineto 0.2 2) (lineto 1.5 2))
}
#(define (multi-mark-engraver ctx)
(let
((texts '())
(final-texts '())
(events '()))
`(
(start-translation-timestep
. ,(lambda (trans)
(set! final-texts '())))
(listeners
(mark-event
. ,(lambda (trans ev)
(set! events (cons ev events)))))
(acknowledgers
(break-alignment-interface
. ,(lambda (trans grob source)
(for-each
(lambda (mark)
(set! (ly:grob-parent mark X) grob))
texts))))
(process-music
. ,(lambda (trans)
(for-each
(lambda (ev)
(let*
(
(mark-grob (ly:engraver-make-grob trans 'RehearsalMark ev))
(label (ly:event-property ev 'label))
(formatter (ly:context-property ctx 'markFormatter))
)
(if
(and (procedure? formatter) (not (markup? label)))
(begin
(if (not (number? label))
(set! label
(ly:context-property ctx 'rehearsalMark)))
(if (and (integer? label)
(exact? label))
(set!
(ly:context-property ctx 'rehearsalMark)
(1+ label)))
(if (number? label)
(set! label (apply formatter (list label ctx)))
(ly:warning "rehearsalMark must have integer value"))))
(if (markup? label)
(begin
(set! (ly:grob-property mark-grob 'text) label)
(let ((dir (ly:event-property ev 'direction)))
(and (ly:dir? dir)
(set! (ly:grob-property mark-grob 'direction) dir))))
(ly:warning "mark label must be a markup object"))
(set! texts (cons mark-grob texts))))
(reverse events))))
(stop-translation-timestep
. ,(lambda (trans)
(if (pair? texts)
(let
((staves (ly:context-property ctx 'stavesFound)) (priority-index 0))
(for-each
(lambda (grob)
(let
((my-priority (ly:grob-property grob 'outside-staff-priority 1500)))
(for-each (lambda (stave) (ly:pointer-group-interface::add-grob grob 'side-support-elements stave)) staves)
(set! (ly:grob-property grob 'outside-staff-priority) (+ my-priority priority-index))
(set! priority-index (1+ priority-index))
(set! final-texts (cons grob final-texts))))
(reverse texts))
(set! texts '())
(set! events '())))))
(finalize
. ,(lambda (trans)
(and
(pair? final-texts)
(for-each
(lambda (grob)
(set! (ly:grob-property grob 'break-visibility) end-of-line-visible))
final-texts)))))))
\score {
\header {
opus = "Op. 261 №7"
}
\new PianoStaff \with {
instrumentName = "11."
\override InstrumentName.font-size = #6
\override InstrumentName.self-alignment-X = #RIGHT
} <<
\new Staff = "правая" \with {}
\relative do' {
\key do \major
\time 2/4
\tempo "Allegretto vivace"
\set Timing.baseMoment = #(ly:make-moment 1/32)
\set Timing.beatStructure = 4, 4, 4, 4
\openBracket
do'32-3 (_[sol-1 re'-4 sol,-1]) mi'16-!-5 \noBeam r16 mi32-3 (_[do-1 fa-4 do-1]) sol'16-!-5 \noBeam r16 |
do,32-3 (_[sol-1 re'-4 sol,-1]) mi'16-!-5 \noBeam r16 mi32-3 (_[do-1 fa-4 do-1]) sol'16-!-5 \noBeam r16 |
fa32-4 (_[sol-5 mi-3 sol-5]) re16-!-2 \noBeam r16 mi32-3 (_[sol-5 re-2 sol-5]) do,16-!-1 \noBeam r16 |
\once \override Fingering.avoid-slur = #'inside
re32-2 (sol-5 re-2 sol-5 si,-1 re-4 si-2 re-4) sol,16-!-1 [sol-!-3 sol-!-2 sol-!-1] \closeBracket |
\openBracket
do32-3 (_[sol-1 re'-4 sol,-1]) mi'16-!-5 \noBeam r16 mi32-3 (_[do fa-4 do]) sol'16-!-5 \noBeam r16 |
\ottava #1 do32-3 (_[sol re'-4 sol,]) mi'16-!-5 \noBeam r16 mi32-3 (_[do fa-4 do]) sol'16-!-5 \noBeam r16 |
\tweak outside-staff-priority #100 \doubleBracket
\once \override Fingering.avoid-slur = #'inside
la32-5 (la,-1 la'-5 sol fa-3 mi re-1 do-4 \ottava #0 si-3 la sol-1 fa-4 mi-3 re do-1 si-2 |
do-1 re mi-3 fa-1 sol-2 la si do-5 do,16-.-1) r r8 \closeBracket
\bar "|."
}
\new Dynamics {
s16
s32 s32 s8 s4 | s2 | s2 |
s32 \> s32 s32 s32 s32 s32 s32 s32 s16 s16 s16 s16 \! |
s32 \p s32 s32 s32 s16 s16 s32 s32 s32 s32 s16 s16 |
s32 \mf s32 s32 s32 s16 s16 s32 s32 s32 s32 s16 s16 |
s32 \f s32 s32 s32 s32 s32 s32 s32 s32 s32 s32 s32 s32 s32 s32 s32 |
}
\new Staff = "левая" \with {}
\relative do {
\clef bass
\set fingeringOrientations = #'(down)
<do-4>16-. _[r <mi-2 sol-1>-.] r do-. _[r <mi sol>-.] r |
<do-4>-. _[r <mi-2 sol-1>-.] r do-. _[r <mi sol>-.] r |
<do-5>-. _[r <re-3 sol-1>-.] r <do-4>-. _[r <mi-2 sol-1>-.] r |
<sol-3 si-1>8-> r8 r4 |
<do,-4>16-. _[r <mi-2 sol-1>-.] r do-. _[r <mi sol>-.] r |
<do-4>-. _[r <mi-2 sol-1>-.] r do-. _[r <mi sol>-.] r |
<fa-5 la-3 re-1>8 r <sol-5 re'-2 fa-1> r |
<do-3 mi-1>16-. r <do mi>-. r <do mi>-. r r8
}
>>
\layout {
\context {
\Score
\override SpacingSpanner.spacing-increment = 1.1
\remove "Mark_engraver"
\consists #multi-mark-engraver
}
}
}
This is where it explodes:
(if (markup? label)
(begin
(set! (ly:grob-property mark-grob 'text) label)
(let ((dir (ly:event-property ev 'direction)))
(and (ly:dir? dir)
(set! (ly:grob-property mark-grob 'direction) dir))))
(ly:warning "mark label must be a markup object"))
The test if the label is a markup fails and the code prints “warning: mark label must be a markup object”. Later Lilypond also prints a number of
programming error: Trying to interpret a non-markup object: ()
continuing, cross fingers
I am not sure where this is coming from at all. There is no line reference.
I tried convert-ly
. It was supposed to convert an outdated version of .ly to an up-to-date one. The resulting .ly produced fewer errors, but it engraved A, B, C, D, E as marks instead of brackets.
How can I replace the functionality of this script?
convert-ly
should have changed\mark
to\textMark
because\mark
accepts only numbers now as an argument.