Problem with merging whole measure rests

2019-07-20 Thread David Wright
There seems to be a problem in the merging whole measure rests
code. With 2.18.2, I'd been using the 336-based snippet from
https://raw.githubusercontent.com/wbsoft/lilymusic/master/include/merge-rests.ily
for some years, though I changed   0)   on the 110th line to   1)
in order to get the correct line on the staff: 2nd line down.

When run with 2.19.83, my modification is no longer necessary,
as it would hang the rests incorrectly from the top line.

Of course with 2.19.83 there's no need to use the 336-based snippet
at all, because Merge_rests_engraver is now built into LP. However,
as p180 of the NR shows in its score example, the rest now hangs
from the top line.

I imagine the error is somewhere after line 121 in
lilypond/usr/share/lilypond/current/scm/scheme-engravers.scm
but patching it looks more difficult than the old snippet.

Obviously 2.18 can't run the NR example, so I've attached some
files that demonstrate the old fix and the new manifestation.
IOW the first two should print correctly but the third prints
as in the NR.

Cheers,
David.
%{
  Based on http://lsr.dsi.unimi.it/LSR/Snippet?id=336
  
  Merges rests and multi-measure rests that occur on the same moment inside a
  staff with two voices.
  
  Usage:
  
  \include "merge-rests"
  
  \layout {
\mergeRests
  }
  
  or inside the music:
  
  \new Staff <<
\relative c' {
  \mergeRestsOn %% in one of the voices is sufficient
  c4 d e f g r r2
}
\\
\relative c' {
  a4 b c d e r r2
}
  >>
 
%}
\version "2.13.50"


#(define (rest-score r)
  (let ((score 0)
(yoff (ly:grob-property-data r 'Y-offset))
(sp (ly:grob-property-data r 'staff-position)))
(if (number? yoff)
(set! score (+ score 2))
(if (eq? yoff 'calculation-in-progress)
(set! score (- score 3
(and (number? sp)
 (<= 0 2 sp)
 (set! score (+ score 2))
 (set! score (- score (abs (- 1 sp)
score))

#(define (merge-rests-on-positioning grob)
  (let* ((can-merge #f)
 (elts (ly:grob-object grob 'elements))
 (num-elts (and (ly:grob-array? elts)
(ly:grob-array-length elts)))
 (two-voice? (= num-elts 2)))
(if two-voice?
(let* ((v1-grob (ly:grob-array-ref elts 0))
   (v2-grob (ly:grob-array-ref elts 1))
   (v1-rest (ly:grob-object v1-grob 'rest))
   (v2-rest (ly:grob-object v2-grob 'rest)))
  (and
   (ly:grob? v1-rest)
   (ly:grob? v2-rest)
   (let* ((v1-duration-log (ly:grob-property v1-rest 'duration-log))
  (v2-duration-log (ly:grob-property v2-rest 'duration-log))
  (v1-dot (ly:grob-object v1-rest 'dot))
  (v2-dot (ly:grob-object v2-rest 'dot))
  (v1-dot-count (and (ly:grob? v1-dot)
 (ly:grob-property v1-dot 'dot-count -1)))
  (v2-dot-count (and (ly:grob? v2-dot)
 (ly:grob-property v2-dot 'dot-count -1
 (set! can-merge
   (and
(number? v1-duration-log)
(number? v2-duration-log)
(= v1-duration-log v2-duration-log)
(eq? v1-dot-count v2-dot-count)))
 (if can-merge
 ;; keep the rest that looks best:
 (let* ((keep-v1? (>= (rest-score v1-rest)
  (rest-score v2-rest)))
(rest-to-keep (if keep-v1? v1-rest v2-rest))
(dot-to-kill (if keep-v1? v2-dot v1-dot)))
   ;; uncomment if you're curious of which rest was chosen:
   ;;(ly:grob-set-property! v1-rest 'color green)
   ;;(ly:grob-set-property! v2-rest 'color blue)
   (ly:grob-suicide! (if keep-v1? v2-rest v1-rest))
   (if (ly:grob? dot-to-kill)
   (ly:grob-suicide! dot-to-kill))
   (ly:grob-set-property! rest-to-keep 'direction 0)
   (ly:rest::y-offset-callback rest-to-keep)))
(if can-merge
#t
(ly:rest-collision::calc-positioning-done grob

#(define merge-multi-measure-rests-on-Y-offset
  ;; Call this to get the 'Y-offset of a MultiMeasureRest.
  ;; It keeps track of other MultiMeasureRests in the same NonMusicalPaperColumn
  ;; and StaffSymbol. If two are found, delete one and return 0 for Y-offset of
  ;; the other one.
  (let ((table (make-weak-key-hash-table)))
(lambda (grob)
  (let* ((ssymb (ly:grob-object grob 'staff-symbol))
 (nmcol (ly:grob-parent grob X))
 (ssymb-hash (or (hash-ref table ssymb)
 (hash-set! table ssymb (make-hash-table
 (othergrob (hash-ref ssymb-hash nmcol)))
(if (ly:grob? othergrob)
(begin
  ;; Found the other grob i

Re: Problem with merging whole measure rests

2019-07-21 Thread Malte Meyn

Hi David,

if I understand correctly you see a problem with the 
Merge_rests_engraver (your attached file from-NR.ly)?


That engraver didn’t merge MultiMeasureRests until 2.19.65 and does so 
since 2.19.80 (the first prerelease for 2.20.0, hence the version number 
jump from 65 to 80). However, merging of MultiMeasureRests gives them an 
incorrect vertical position in 2.19.80–2.19.83. The not yet released 
2.21.0 fixes this.


@someone who knows about such things: Would it make sense to cherry-pick 
that fix into the stable/2.20 branch?


Cheers,
Malte

Am 20.07.19 um 18:55 schrieb David Wright:

Obviously 2.18 can't run the NR example, so I've attached some
files that demonstrate the old fix and the new manifestation.
IOW the first two should print correctly but the third prints
as in the NR.


___
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user