+
+ (define (analyse-silence)
+ (let ((rests1 (if vs1 (rest-and-skip-events vs1) '()))
+ (rests2 (if vs2 (rest-and-skip-events vs2) '())))
+ (cond
+
+ ;; multi-measure rests (probably), which the
+ ;; part-combine iterator handles well
+ ((and (synced? now-state)
+ (= 0 (length rests1))
+ (= 0 (length rests2)))
+ (set! (configuration now-state) 'unisilence))
+
+ ;; equal rests or equal skips, but not one of each
+ ((and (synced? now-state)
+ (= 1 (length rests1))
+ (= 1 (length rests2))
+ (equal? (ly:event-property (car rests1) 'class)
+ (ly:event-property (car rests2) 'class))
+ (equal? (ly:event-property (car rests1) 'duration)
+ (ly:event-property (car rests2) 'duration)))
+ (set! (configuration now-state) 'unisilence))
+
+ ;; rests of different durations or mixed with
+ ;; skips or multi-measure rests
+ ((synced? now-state)
+ ;; TODO When one part has a rest and the other has a
+ ;; multi-measure rest, tell the part-combine
+ ;; iterator to route the part with the rest to the
+ ;; shared voice. Until there is a way to do this,
+ ;; we print them both; it does not look very good,
+ ;; but failing to print the rest is misleading.
+ ;;
+ ;; Maybe do something similar for skips; route
+ ;; the rest to the shared voice and the skip to
+ ;; the voice for its part.
+ (set! (configuration now-state) 'apart-silence))
+
+ ;; TODO At a multi-measure rest, return to unisilence
+ ;; even after having been apart. The results are not
+ ;; good now because of the deficiency mentioned
+ ;; above.
+ )))
+
+ (if (or vs1 vs2)
+ (let ((notes1 (if vs1 (note-events vs1) '()))
+ (notes2 (if vs2 (note-events vs2) '())))
+ ; Todo: What about a2 chords, e.g. string multi-stops?
+ ; Sort and compare notes1 and notes2?
+ (cond ((and (equal? (configuration now-state) 'chords)
+ (= 1 (length notes1))