Le 17/11/2021 à 20:50, Dimitris Marinakis a écrit :
I need a generic engraver that works similar to the default arpeggio
one but I don't want to override the arpeggio engraver or any other
default ones in case I need to have multiple events simultaneously.
I saw a similar thread with a custom arpeggio stencil that had both up
and down arrows but I need to keep this engraver its own thing in this
case.
I thought about searching inside the lilypond internal files to see
how the default arpeggio spanner works but if someone else can help me
through this I'd really appreciate it.
Essentially, I'm interested in the ability of the arpeggio spanner to
calculate its length based on the distance of the outer notes. I will
replace the line stencil with something that will scale up/stretch
depending on the vertical length of that spanner.
Sorry if my terminology is wrong (engraver, spanner etc.)
How about this?
\version "2.22.1"
#(define-event-class 'custom-arpeggio-event 'music-event)
#(define (define-event! type properties)
(set-object-property! type
'music-description
(cdr (assq 'description properties)))
(set! properties (assoc-set! properties 'name type))
(set! properties (assq-remove! properties 'description))
(hashq-set! music-name-to-property-table type properties)
(set! music-descriptions
(sort (cons (cons type properties)
music-descriptions)
alist<?)))
#(define-event!
'CustomArpeggioEvent
'((types . (custom-arpeggio-event post-event event))
(description . "")))
#(set-object-property! 'CustomArpeggio 'is-grob? #t)
#(set-object-property! 'CustomArpeggio 'translation-type?
ly:grob-properties?)
\layout {
\context {
\Global
\grobdescriptions #(acons 'CustomArpeggio
(assq-ref all-grob-descriptions 'Arpeggio)
all-grob-descriptions)
}
}
#(ly:register-translator
(lambda (context)
(let ((arpeggio-event #f)
(arpeggio #f))
(make-engraver
(listeners
((custom-arpeggio-event engraver event)
(set! arpeggio-event event)))
((process-music engraver)
(if arpeggio-event
(set! arpeggio
(ly:engraver-make-grob engraver 'CustomArpeggio
arpeggio-event))))
(acknowledgers
((rhythmic-head-interface engraver grob source-engraver)
(if arpeggio
(ly:pointer-group-interface::add-grob arpeggio
'side-support-elements grob)))
((stem-interface engraver grob source-engraver)
(if arpeggio
(begin
(ly:grob-set-parent! arpeggio Y grob)
(ly:pointer-group-interface::add-grob arpeggio
'stems grob))))
((note-column-interface engraver grob source-engraver)
(if arpeggio
(ly:pointer-group-interface::add-grob grob
'conditional-elements arpeggio)))
((arpeggio-interface engraver grob source-engraver)
; NB ==============================================
; Place custom arpeggios on the left of normal ones.
; If this is not what you want, flip 'arpeggio' and
; 'grob' below.
; =================================================
(ly:pointer-group-interface::add-grob arpeggio
'side-support-elements grob)))
((stop-translation-timestep engraver)
(set! arpeggio-event #f)
(set! arpeggio #f)))))
'Custom_arpeggio_engraver
'())
\layout {
\context {
\Voice
\consists Custom_arpeggio_engraver
}
}
customArpeggio = #(make-music 'CustomArpeggioEvent)
{
<c' c''>\customArpeggio
\override CustomArpeggio.color = red
<c' c''>\arpeggio\customArpeggio
}
The engraver is adapted from the default Arpeggio_engraver,
of which the C++ code can be found at
https://gitlab.com/lilypond/lilypond/-/blob/master/lily/arpeggio-engraver.cc
For information on Scheme engravers, see
https://extending-lilypond.readthedocs.io/en/latest/translation.html
To get the vertical extent of the CustomArpeggio in
a stencil callback, read the 'positions property. For
example:
\score {
\layout {
#(layout-set-staff-size 30)
}
{
\override CustomArpeggio.stencil =
#(lambda (grob)
(let ((positions (interval-scale (ly:grob-property grob
'positions)
(ly:staff-symbol-staff-space grob))))
(ly:stencil-translate-axis
(grob-interpret-markup
grob
(make-draw-squiggle-line-markup
0.5
(cons 0 (interval-length positions))
#t))
(car positions)
Y)))
<c c''>\arpeggio\customArpeggio
}
}
Best,
Jean