Hi Mark,
parenthesizeMusic function
This is wonderful! Thank you!
This is a slight error, which I don't have the skills to fix, in that
there is no closing paren if music consists of a single note (a
first/last problem?). Otherwise, straight into the library!
Make that:
parenthesizeMusic =
#(define-music-function (music) (ly:music?)
(define ((stencils which) grob)
(let* ((stens (parentheses-item::calc-parenthesis-stencils grob))
(sten (which stens)))
(if (eq? which first) (list sten point-stencil) (list point-stencil
sten))))
(define (add-tweak event tweak)
(ly:music-set-property! event 'tweaks
(cons tweak (ly:music-property event 'tweaks '()))))
(let ((evs (extract-typed-music music 'rhythmic-event)))
(ly:music-set-property! (first evs) 'parenthesize #t)
(if (pair? (cdr evs))
(begin
(ly:music-set-property! (last evs) 'parenthesize #t)
(add-tweak (first evs) `((ParenthesesItem . stencils) .
,(stencils first)))
(add-tweak (last evs) `((ParenthesesItem . stencils) .
,(stencils second))))))
music)
Explanation: The additional (if (pair? (cdr evs)) ...) checks if there's
more than one rhythmic event in the given music before parenthesising
the last event and cancelling the unnecessary half of each pair of
parentheses.
(Why this works: evs is a list of events (a b ...). Now (cdr evs) is the
tail (b ...) of that list. This is non-empty iff it is a pair, since
scheme lists are internally nested pairs: '(1 2 3) is '(1 . (2 . (3 .
()))) - which is also the reason why cdr, which returns the second
element of a pair, returns the tail of a list.)
Thanks, Aaron, for this truly wonderful function (and please forgive me
for messing with your code).
Lukas