Am 09.03.2018 um 11:45 schrieb Arttu Punkkinen:

I was wondering, if there is a way to specify a multimeasure rest which length is only relatively defined so that it ends at predetermined bar number?

I often find myself needing to adjust or add material between multimeasure rests, which currently need manual adjustment to keep alignment.

Not for bar numbers but for “anchors” that can be placed in a separate music expression, you could use the code below. You find the file alignTo.ily attached. This is a modified version of the file posted here:

The following commands are defined:
• \anchor, to be used as
        \anchor "anchorname"
• \until, to be used as
        s \until "anchorname"
        R \until "anchorname"
or even
        f \until "anchorname"
The latter for long notes is probably useful only if you use the Completion_heads_engraver.
• \quoteUntil, to be used as
        \quoteUntil "instrument" "anchorname"
Here you have to use \alignTo in the \addQuote command for correct results.
• \alignTo and \useAndAlignTo, to be used as
        \alignTo \anchormusic \music
The former only makes use of the anchors, the latter also uses the music of \anchormusic (f. e. key signature changes).

Thanks to the original authors!


\version "2.19.81"

\include "alignTo.ily"

global = {
  \key es \major
  \anchor "1st theme"
  \time 3/4
  \anchor "mid"
  \anchor "coda"
  \tempo "Coda"
  s2. \bar "|."

flute = \relative {
  R \until "1st theme"
  es'4 f g as bes c d2.
  s \until "mid"
  es4 d c bes as g f es f es2.
\addQuote "flute" \alignTo \global \flute

clarinet = \relative {
  \transposition bes
  R \until "mid"
  es4 f g as bes c
  \quoteUntil "flute" "coda"
\addQuote "clarinet" \alignTo \global \clarinet

\new StaffGroup <<
  \new Staff \useAndAlignTo \global \flute
  \new Staff \transpose bes c' \useAndAlignTo \global \clarinet
\version "2.19.25"

#(define anchor-color blue)

% slightly modified/improved version of
% alignTo from
alignTo =
#(define-music-function (conductor music) (ly:music? ly:music?)
   "Lengthen any note or rest in the sequence MUSIC just before each tag
that matches a tag in the sequence CONDUCTOR, so that the tags occur
at the same times from to the beginnings of MUSIC and CONDUCTOR."
   (define (find-sequence music)
     (or (fold-some-music
          (lambda (x) (music-is-of-type? x 'sequential-music))
          (lambda (x e1) (or e1 ; use the first nonempty sequence
                             (let ((es (ly:music-property x 'elements)))
                               (if (null? es) #f es))))
          (ly:input-warning (ly:music-property music 'origin)
            "alignTo: cannot find sequential music")
   (let loop ((aligner (find-sequence conductor))
              (alignee (find-sequence music))
              (time-left (ly:music-length conductor)))
     (case (length alignee)
       ((0) music)
       ((1) music)
        (let* ((a (first alignee)) ; music that might be lengthened,
                (b (second alignee)) ; if this music is tagged
                ; if a has an until property, add this to tag (which is b’s 
                (tag (if (not (null? (ly:music-property a 'until)))
                         (cons (ly:music-property a 'until)
                           (ly:music-property b 'tags))
                         (ly:music-property b 'tags)))
                (tail (and (not (null? tag))
                            (lambda (x)
                              (not (null? (lset-intersection
                                           eq? tag
                                           (ly:music-property x 'tags)))))
          (if tail
              (let ((tail-length (ly:music-length
                                  (make-sequential-music tail))))
                (if (ly:moment<? time-left tail-length)
                    (ly:input-warning (ly:music-property b 'origin)
                      "alignTo: already beyond conductor's tag ~a"
                       eq? tag
                       (ly:music-property (car tail) 'tags)))
                    (let ((newdur
                            (ly:moment-sub time-left tail-length))))
                      (if (eq? (ly:music-property a 'name) 'QuoteMusic)
                           (if (null? (ly:music-property a 'until))
                               (ly:input-warning (ly:music-property a 'origin)
                                 "alignTo: cannot scale quoteDuring correctly, 
please use quoteUntil"))
                           (ly:music-set-property! a 'element
                             (if (null? (ly:music-property a 'quote-color))
                                 (make-music 'SkipEvent
                                   'duration newdur)
                                  (make-music 'SkipEvent
                                    'duration newdur)))))
                          (ly:music-set-property! a 'duration newdur))))))
          (loop (or tail aligner)
            (cdr alignee)
            (ly:moment-sub time-left (ly:music-length a))))))))

useAndAlignTo =
#(define-music-function (global music) (ly:music? ly:music?)
       #(alignTo global music)

anchor =
#(define-music-function (text) (string?)
   (if (ly:get-option 'point-and-click)
         \tag #(string->symbol text)
         \single \override RehearsalMark.self-alignment-X = #LEFT
         \mark \markup \with-color #anchor-color #text
         \tag #(string->symbol text) s1*0

until =
#(define-music-function (anchor) (string?)
     \tag #(string->symbol anchor) s1*0

% don’t redefine quoteUntil if advancedQuote.ily was included before
% because of different transposition behaviour
#(if (not (defined? 'quoteUntil))
     (define quoteUntil
       (define-music-function (what anchor) (string? string?)
         (make-music 'QuoteMusic
           'until (string->symbol anchor)
           'quoted-music-name what))))
lilypond-user mailing list

Reply via email to