Op dinsdag 17 augustus 2010 schreef Xavier:

> On Fri, Jun 11, 2010 at 3:27 PM, Xavier Scheuer <x.sche...@gmail.com> wrote:
>> Could you implement the possibility:
>>  \override RestCollision #'positioning-done =
>> #merge-rests-on-positioning described in
>> http://lsr.dsi.unimi.it/LSR/Item?id=336
>> _directly_ into LilyPond?
> 
> Graham wrote: Patches will be reviewed.

This is my first stab at this. It just uses the code in LSR336 but provides a 
few convenience commands.

The major limitation is that multimeasure rests are not yet taken into 
account: they are simply moved to the central staff position, whether they 
occur in both voices or not.

AFAICT MultiMeasureRest objects do not take part in some collision. Is there a 
way to get the other one in the other voice in a staff? Then I could write a 
function to assign to the 'Y-offset property of the MMrest.

If the MMrests function well, this file could be added to the ly/ directory of 
lilypond, it could then be included if people want to use the functionality.

best regards,
Wilbert Berendsen

-- 
Frescobaldi, LilyPond editor for KDE: http://www.frescobaldi.org/
Nederlands LilyPond forum: http://www.lilypondforum.nl/
%{
  Based on http://lsr.dsi.unimi.it/LSR/Snippet?id=336
  
  Merges 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 if sufficient
      c4 d e f g r r2
    }
    \\
    \relative c' {
      a4 b c d e r r2
    }
  >>
 
  TODO:
  - Fix MultiMeasureRests, currently they are always shifted to the center staff
    position.
    
    How to find out if there are two MultiMeasureRests at the same moment?
  
%}
\version "2.12.3"


#(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))))

mergeRestsOn = {
  \override Staff.RestCollision #'positioning-done = #merge-rests-on-positioning
  \override Staff.MultiMeasureRest #'Y-offset = #0
}

mergeRestsOff = {
  \revert Staff.RestCollision #'positioning-done
  \revert Staff.MultiMeasureRest #'Y-offset
}

mergeRests = \layout {
  \context {
    \Staff
    \override RestCollision #'positioning-done = #merge-rests-on-positioning
    \override MultiMeasureRest #'Y-offset = #0
  }
}

   
_______________________________________________
bug-lilypond mailing list
bug-lilypond@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-lilypond

Reply via email to