2016-11-08 11:44 GMT+01:00 Urs Liska <u...@openlilylib.org>: > Hello all, > > On https://github.com/openlilylib/snippets/issues/123 it was reported > that the engraver merging rests > (https://github.com/openlilylib/snippets/tree/master/editorial-tools/merge-rests-engraver) > fails to merge dots of dotted rests. This can be seen here: > http://lilybin.com/r1jcpm/3 > > I think this should be quite easy to fix and update, but I don't know > how to do it in that engraver. So any solution would be welcome. If > you're an openLilyLib user/contributor you may do this directly as a > pull request. > > Thanks > Urs
Hi Urs, how about the code below? I did some general updating as well. Just in case I overlooked something, thorough testing is recommended ;) \version "2.19.49" #(define merge-rests-engraver (lambda (context) (let ((rests '()) (dots '()) (moment=? (lambda (a b) (not (or (ly:moment<? a b) (ly:moment<? b a)))))) (make-engraver ((start-translation-timestep trans) ;; reset dots and rests to empty lists for each time-step (set! rests '()) (set! dots '())) ((stop-translation-timestep trans) (let (;; get a list of the rests 'duration-lengths, 'duration-log does ;; not take dots into account (durs (map (lambda (g) (ly:duration-length (ly:prob-property (ly:grob-property g 'cause) 'duration))) rests))) ;; merge rests only when at least two rest with equal duration-length ;; are present, by letting them print one upon the other. In this ;; case suicide the (possible) dots of all but the first rest. (if (and (>= (length rests) 2) (not (any (lambda (x) (not (moment=?(car durs) x))) durs))) (begin (for-each (lambda (rest) (ly:grob-set-property! rest 'Y-offset 0)) rests) (if (pair? dots) (for-each ly:grob-suicide! (cdr dots))))))) (acknowledgers ;; We go for 'dot-column-interface to catch the dots, because we're ;; interested in the dots _in_ the column, not single dots per Voice. ((dot-column-interface engraver grob source-engraver) (set! dots (append (ly:grob-array->list (ly:grob-object grob 'dots)) dots))) ((rest-interface engraver grob source-engraver) ;; we go for grob::name, because 'rest-interface would probably ;; catch MMRS as well. ;; n.b. grob::name is not present in 2.18.2, use instead ;(if (eq? 'Rest (assoc-ref (ly:grob-property grob 'meta) 'name)) (if (eq? (grob::name grob) 'Rest) (set! rests (cons grob rests))))))))) %%%%%%%%%%%%%%%%%%%%%%%%%%% %% Example %%%%%%%%%%%%%%%%%%%%%%%%%%% \score { \new Staff << \new Voice { \voiceOne r4. \oneVoice r4. \voiceOne r4. r4 } \new Voice { \voiceTwo r4. s4. r4 s8 r4. } >> \layout { \context { \Staff \consists #merge-rests-engraver } % merges non-whole rests } } Cheers, Harm _______________________________________________ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user