lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Merge Rests Engraver


From: Jay Anderson
Subject: Re: Merge Rests Engraver
Date: Wed, 22 Feb 2012 22:17:35 -0700

On Wed, Feb 22, 2012 at 10:13 AM, Carl Sorensen <address@hidden> wrote:
> If this were a C++ engraver, I would expect the unused grobs to be
> suicided.  Is there a reason not to do this in a scheme engraver?  I think
> it is unwise to keep multiple copies of a grob around and trust that they
> are the same.

Well, if I call ly:grob-suicide! on one of the rests and it has text
attached to it a segfault results. I'm not sure how to prevent this. I
assume these items would need to be re-parented somehow.

On Wed, Feb 22, 2012 at 8:45 AM, David Nalesnik
<address@hidden> wrote:
> I don't have an answer to your question about overlapping grobs, just a
> suggestion: could you generalize this to deal with more than two voices?
>  (Maybe you could collect the acknowledged rests into a list, rather than
> using separate variables rest-a, rest-b, etc. Just a thought.)

Is this ever done though? I've only ever seen rests combined with two
voices. It would also complicate things somewhat, but it could be
doable. We have to check that all rests found at a time step are the
same length. Also, I don't think it would ever make sense to attempt
to merge a subset. All or nothing.

I did notice a problem with what I had though. For checking the
multi-measure rest length I looked at the cause length, but multiple
multi-measure rest grobs could have a common cause. So if we had
something like << {R1*3 |} \\ {R1 | R1 | R1 |} >> they wouldn't be
merged. I can't quite figure out how to check the length of the
measure that the grob is representing though. The best I can think of
is to keep around potential pairs until the finalize step and do all
the merging then when the measure-count is available. Any better
solutions?

Also for simplicity sake it would probably make sense to separate out
the regular rest merging engraver from the multi-measure-rest engraver
since regular rests are much easier to deal with:

#(define merge-rests-engraver
   (lambda (context)
     (let ((same-length (lambda (rest-a rest-b)
                          (eq? (ly:grob-property rest-a 'duration-log)
(ly:grob-property rest-b 'duration-log))))
           (rest-a #f)
           (rest-b #f))
     `((start-translation-timestep . ,(lambda (trans)
                                        (set! rest-a #f)
                                        (set! rest-b #f)))
       (stop-translation-timestep . ,(lambda (trans)
                                       (if (and rest-a rest-b
(same-length rest-a rest-b))
                                         (begin
                                           (ly:grob-set-property!
rest-a 'Y-offset 0)
                                           (ly:grob-set-property!
rest-b 'Y-offset 0)))))
       (acknowledgers
         (rest-interface . ,(lambda (engraver grob source-engraver)
                              (if (eq? 'Rest (assoc-ref
(ly:grob-property grob 'meta) 'name))
                                (if rest-a
                                  (set! rest-b grob)
                                  (set! rest-a grob))))))))))

-----Jay



reply via email to

[Prev in Thread] Current Thread [Next in Thread]