[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Nice workaround for simultaneous rehearsal marks – thanks Neil!

From: Xavier Scheuer
Subject: Nice workaround for simultaneous rehearsal marks – thanks Neil!
Date: Sun, 7 Aug 2011 17:09:28 +0200


I have had a nice conversation with Neil, in which I said that

  "Within my "Most Annoying everyday-use Issues" there is also the fact
  that it is not possible to have two simultaneous rehearsal marks (and
  the workaround of LSR #575 is really dirty

the result of which Neil creates a nice workaround that permits to have
simultaneous rehearsal marks and —the icing* on the cake— it allows
these rehearsal marks to have different settings.

[*] in French we say "the _cherry_ on the cake".

Very useful if you want one rehearsal mark at the end of a line with
some settings and another one at the begin of the following line with
different settings (see example below for right aligned "to coda" and
at the following line a normal \mark \default).
It also allows to print two rehearsal marks above and below the same

IMHO that could replace easily the different workarounds one can find:

%%%% Snippet

\version "2.15.8"

#(define (multi-mark-engraver ctx)
   (let ((texts '())
         (final-texts '())
         (events '()))

        . ,(lambda (trans)
             (set! final-texts '())))

         . ,(lambda (trans ev)
              (set! events (cons ev events)))))

         . ,(lambda (trans grob source)
              (for-each (lambda (mark)
                          (set! (ly:grob-parent mark X) grob))

        . ,(lambda (trans)
              (lambda (ev)
                (let* ((mark-grob
                        (ly:engraver-make-grob trans 'RehearsalMark ev))
                       (label (ly:event-property ev 'label))
                       (formatter (ly:context-property ctx 'markFormatter)))

                  (if (and (procedure? formatter)
                           (not (markup? label)))
                       (if (not (number? label))
                           (set! label
                                 (ly:context-property ctx 'rehearsalMark)))

                       (if (and (integer? label)
                                (exact? label))
                           (set! (ly:context-property ctx 'rehearsalMark)
                                 (1+ label)))

                       (if (number? label)
                           (set! label (apply formatter (list label ctx)))
                           (ly:warning "rehearsalMark must have
integer value"))))

                  (if (markup? label)
                       (set! (ly:grob-property mark-grob 'text) label)
                       (let ((dir (ly:event-property ev 'direction)))
                         (and (ly:dir? dir)
                              (set! (ly:grob-property mark-grob 'direction)
                      (ly:warning "mark label must be a markup object"))

                  (set! texts (cons mark-grob texts))))
              (reverse events))))

        . ,(lambda (trans)
             (if (pair? texts)
                 (let ((staves (ly:context-property ctx 'stavesFound))
                       (priority-index 0))
                   (for-each (lambda (grob)
                               (let ((my-priority (ly:grob-property
grob 'outside-staff-priority 1500)))
                                 (for-each (lambda (stave)

(ly:pointer-group-interface::add-grob grob 'side-support-elements
                                 (set! (ly:grob-property grob
'outside-staff-priority) (+ my-priority priority-index))
                                 (set! priority-index (1+ priority-index))
                                 (set! final-texts (cons grob final-texts))))
                             (reverse texts))
                     (set! texts '())
                     (set! events '())))))

         . ,(lambda (trans)
              (and (pair? final-texts)
                   (for-each (lambda (grob)
                               (set! (ly:grob-property grob 'break-visibility)

\layout {
 \context {
   \remove "Mark_engraver"
   \consists #multi-mark-engraver
   \consists "Tweak_engraver"

markDown =
#(define-music-function (parser location text) (markup?)
   (make-music 'MarkEvent
               'direction DOWN
               'label text))

myMark =
#(define-music-function (parser location text) (markup?)
  (make-music 'MarkEvent
              'label text))

toCoda = {
 \tweak #'self-alignment-X #RIGHT
 \tweak #'break-visibility #begin-of-line-invisible
 \myMark \markup { to \hspace #1.25 \raise #1.25 \musicglyph #"scripts.coda" }

\relative c' {
 c1 | c | c | c \toCoda
 \bar "||" \break
 \mark \default
 c1 | c |
 \mark \default
 \markDown "23"
 c | c

%%%% End of snippet


Xavier Scheuer <address@hidden>

reply via email to

[Prev in Thread] Current Thread [Next in Thread]