On Wed, Sep 05, 2012 at 01:17:35AM -0700, eluze wrote: > > Frank Steinmetzger wrote > > > > > > While the empty staves get removed as expected, using this feature breaks > > the > > merge-rests code -- I get two rests above each other. > > > > for me it works - can you provide an example?
OK, finally I found the time to deal with this. I found out that among the
things that \RemoveEmptyStaffContext changes are the settings that merge rests.
I attached a mini-example to demonstrate. In my normal setup I have a global
include file which pre-defines some layout stuff. It has a layout block which,
to enable merging of rests, contains:
\context {
\Staff
\override RestCollision #'positioning-done = #merge-rests-on-positioning
\override MultiMeasureRest #'Y-offset = #merge-multi-measure-rests-on-Y-offset
}
I simulated this in my attached example by having a \layout block at the top
of the file. The result is that, as soon as I add \RemoveEmptyStaffContext to
the score, the rests are no longer merged. I need to repeat the code from the
global \layout block in the score's \layout (*below* \RemoveEmptyStaffContext).
--
Gruß | Greetings | Qapla'
Please do not share anything from, with or about me with any Facebook service.
They say memory is the second thing to go. I forgot what the first thing was.
#(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-rest-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, make transparent one and return 1 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 (begin
(if (not (hash-ref table ssymb))
(hash-set! table ssymb (make-hash-table 1)))
(hash-ref table ssymb)))
(othergrob (hash-ref ssymb-hash nmcol))
(measure-count (if (ly:grob? grob)
(ly:grob-property grob 'measure-count)
0)))
(if (ly:grob? othergrob)
(begin
;; Make merged rest transparent instead of suiciding
;; in case it supports text/counter
(set! (ly:grob-property othergrob 'transparent) #t)
(hash-remove! ssymb-hash nmcol)
(if (<= (string->number (cadr (string-split (lilypond-version)
#\.))) 14)
0
(if (< 1 measure-count)
0
1))
)
(begin
;; Just save this grob and return the default value
(hash-set! ssymb-hash nmcol grob)
(ly:staff-symbol-referencer::callback grob)))
))))
mergeRestsOn = {
\override Staff.RestCollision #'positioning-done = #merge-rests-on-positioning
\override Staff.MultiMeasureRest #'Y-offset =
#merge-multi-measure-rest-on-Y-offset
}
mergeRestsOff = {
\revert Staff.RestCollision #'positioning-done
\revert Staff.MultiMeasureRest #'Y-offset
}
mergeRests = \with {
\override RestCollision #'positioning-done = #merge-rests-on-positioning
\override MultiMeasureRest #'Y-offset = #merge-multi-measure-rest-on-Y-offset
}
mmrtr = \override Voice.MultiMeasureRestNumber #'transparent = ##t
\version "2.14.2"
% Snippet to auto-merge rests
\include "336.ily"
\paper {
ragged-right = ##t
}
notesone=\relative c'' {
a4 b r b
R1
a1
}
notestwo=\relative c'{
f4 r r f
R1
c1
}
\layout {
\context {
\Staff
\override RestCollision #'positioning-done =
#merge-rests-on-positioning
\override MultiMeasureRest #'Y-offset =
#merge-multi-measure-rest-on-Y-offset
}
}
\score {
<<
\new Staff {
\clef treble
\time 4/4
\new Voice = "EmptyFirst" \relative c'' {
R1 * 3
c1~
c1~
c1
}
}
\new Staff {
\clef treble
\time 4/4
<<
\new Voice = "VoiceOne" {
\voiceOne
\notesone \break
\notesone
}
\new Voice = "VoiceTwo" {
\voiceTwo
\notestwo
\notestwo
}
>>
}
>>
\layout {
indent = #0
\context { \RemoveEmptyStaffContext }
\context {
\Score
\override VerticalAxisGroup #'remove-first = ##t
}
% for rest-merges to work, I need to write the following again
%\context {
% \Staff
% \override RestCollision #'positioning-done =
#merge-rests-on-positioning
% \override MultiMeasureRest #'Y-offset =
#merge-multi-measure-rest-on-Y-offset
%}
}
}
signature.asc
Description: Digital signature
_______________________________________________ lilypond-user mailing list [email protected] https://lists.gnu.org/mailman/listinfo/lilypond-user
