Am Freitag, 2. Februar 2024, 16:38:22 CET schrieb Lukas-Fabian Moser:
> ... and without any new insight, but with a healthy dose of syntactic sugar:

And with a rather simple custom engraver Lilypond will do these kinds of 
things for us.

Cheers, Valentin
\version "2.24"

#(set-object-property! 'gatherAlternatingTimeSignatures
                       'translation-type?
                       boolean?)

#(set-object-property! 'alternatingTimeSignatureTextFunction
                       'translation-type?
                       procedure?)

alternateTimeMarkup = 
#(define-scheme-function (times) (list?)
   (make-line-markup
    (map
     (lambda (x)
       (make-compound-meter-markup
        (list (ly:music-property x 'numerator)
              (ly:music-property x 'denominator))))
     times)))

#(define (alternating-time-translator context)
   (let ((alternate-time-position 0) (alternate-times '()) (last-measure 0) (cause '()))
     (make-engraver
      ((start-translation-timestep engraver)
       (if (not (null? alternate-times))
           (let ((current-measure (ly:context-property context 'currentBarNumber)))
             (if (not (= current-measure last-measure))
                 (begin
                  (set! alternate-time-position
                        (remainder (1+ alternate-time-position) (length alternate-times)))
                  (let* ((ts (list-ref alternate-times alternate-time-position))
                         (cb ((ly:music-property ts 'elements-callback) ts))
                         (proc (ly:music-property (ly:music-property (car cb) 'element) 'procedure))
                         (tsfrac (ly:context-property context 'timeSignatureFraction)))
                    (proc context)
                    ; resetting the ts fraction avoids printing of ts
                    (if (ly:context-property context 'gatherAlternatingTimeSignatures #t)
                        (ly:context-set-property! context 'timeSignatureFraction tsfrac)))
                  (set! last-measure current-measure))))))
      (listeners
       ((time-signature-event engraver event)
        (set! alternate-times (ly:event-property event 'alternate-times))
        (set! cause (if (not (null? alternate-times)) event '()))
        (set! alternate-time-position 0)
        (set! last-measure (ly:context-property context 'currentBarNumber))))
      (acknowledgers
       ((time-signature-interface engraver grob source-engraver)
        (if (and (ly:context-property context 'gatherAlternatingTimeSignatures #t)
                 (not (null? alternate-times)))
            (begin
             (ly:grob-set-property! grob 'stencil ly:text-interface::print)
             (ly:grob-set-property! grob 'text
                                    ((ly:context-property
                                      context
                                      'alternatingTimeSignatureTextFunction
                                      alternateTimeMarkup) alternate-times))))
        (if (and (null? (ly:grob-property grob 'cause)) (not (null? alternate-times)))
            (ly:grob-set-property! grob 'cause cause)))))))

alternateTime =
#(define-music-function (times) (list?)
   (let* ((times (map (lambda (t) (if (ly:music? t) t (time '() t))) times))
          (firstts (ly:music-deep-copy (car times))))
     (ly:music-set-property! firstts 'alternate-times times)
     firstts))

\layout {
  \context {
    \Score
    \consists #alternating-time-translator
  }
}

\new Staff
{
  \alternateTime #'((6 . 8) (5 . 8))
  \repeat unfold 66 a'8
  \time 7/8
  \repeat unfold 14 a'8
}

\new Staff
{
  \alternateTime #'((6 . 8) (5 . 8) (2 . 8))
  \repeat unfold 65 a'8
  \time 7/8
  \repeat unfold 14 a'8
}

\new Staff
{
  \alternateTime #(list (time '(2 3 1) '(6 . 8)) (time '(2 3) '(5 . 8)))
  \repeat unfold 66 a'8
  \time 7/8
  \repeat unfold 14 a'8
}

\new Staff
{
  \set Score.gatherAlternatingTimeSignatures = ##f
  \alternateTime #'((6 . 8) (5 . 8))
  \repeat unfold 66 a'8
  \time 7/8
  \repeat unfold 14 a'8
}

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to